AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Image conversions and capturing with GDI+
Goto page 1, 2, 3, 4, 5, 6, 7  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
PhiLho



Joined: 27 Dec 2005
Posts: 6702
Location: France (near Paris)

PostPosted: Fri Aug 18, 2006 4:58 pm    Post subject: Image conversions and capturing with GDI+ Reply with quote

In an article, Goyyah explained how to do BMP to JPEG Conversion with a third party DLL (dilib.dll).
I immediately thought: "Why use a third party DLL that has to be installed, when Windows now provide such facility with GDI+?".
GDI+ (gdiplus.dll) is provided by default in the latest versions of Windows, and can be installed freely on older versions.

So I started to look at the GDI+ API.
Ow! It wasn't so simple at all!
First problem: GDI+ is (AFAIK) really a bunch of pure C functions, and Microsoft created a C++ wrapper around them, to offer an object-oriented interface. It is nice if you use C++, some .NET language or other OO languages, but it is unusable in AutoHotkey, of course.
MS provides a "flat API", ie. access to the pure C functions, but under-document them to discourage its use...
Fortunately, Visual Basic (and PowerBASIC) users has the same problem, solved it, and provided some samples of flat API use.
Here comes the second problem: this interface might be flexible, but it is awful to use!
You have to convert, for some obscure reason, good Mime types like image/jpeg, to arcane GUIDs like {1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}, it abuses of pointers to pointers, opaque structures, and so on.
I had hard time converting the examples and even harder making them work!

Well, finally, I successed (otherwise I would be in the Ask for Help section...).
So, here is a simple script, converting a file of whatever read format supported by GDI+ (BMP, JPeg, Gif, PNG, Tiff, WMF, EMF, icon) to whatever write format it supports (BMP, JPG, GIF, PNG, TIF).
It uses the GDIplusWrapper.ahk file (wrapper around some GDI+ functions) which depends on the DllCallStruct.ahk library, which itself depends on BinaryEncodingDecoding.ahk...
[EDIT] Note: holomind already used this library to take screenshots. Great! For compactness, he gathered all necessary functions in one file.
I summarize here the functions to copy from DllCallStruct (BinaryEncodingDecoding is actually not used, here only because of generic inclusion of files in generic library files): GetUnicodeString, GetAnsiStringFromUnicodePointer (all strings in GDI+ are encoded in Unicode) and GetInteger/SetInteger. Just copy these functions in your copy of GDIplusWrapper and you have a nice, compact library. Smile

The test code was short, I used to just give it here, but it gets longer, so just download it:
TestGDIplus.ahk

I don't plan to extend much this library right now, but I am open to suggestions. I think it opens a whole world of image creation/alteration...

[EDIT 4] 1.04.000 -- 2006/10/02 (PL) -- Added GDIplus_FreeImage.
[EDIT 3] 1.03.000 -- 2006/09/15 (PL) -- Added GDIplus_CaptureScreenRectangle.
[EDIT 2] 1.02.000 -- 2006/08/22 (PL) -- Added GDIplus_LoadBitmapFromClipboard.
[EDIT 1] 1.01.000 -- 2006/08/21 (PL) -- Some fixes, support of more parameters.
The interface for parameters is changed.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Last edited by PhiLho on Mon Oct 02, 2006 10:15 am; edited 10 times in total
Back to top
View user's profile Send private message Visit poster's website
robiandi



Joined: 08 Aug 2006
Posts: 50

PostPosted: Fri Aug 18, 2006 6:29 pm    Post subject: Reply with quote

I didn't found http://www.autohotkey.net/~PhiLho/GDIplusWrapper.ahk
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5298

PostPosted: Sun Aug 20, 2006 6:54 am    Post subject: Reply with quote

robiandi wrote:
I didn't found http://www.autohotkey.net/~PhiLho/GDIplusWrapper.ahk


Dear PhiLho, Very Happy

Are you not in town? The link is still not working! ...
Eagerly waiting.
Regards,

@Titan: If you're reading this .., Please let us know if there is a typo in the URL.
_________________
SKAN - Suresh Kumar A N
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6702
Location: France (near Paris)

PostPosted: Mon Aug 21, 2006 8:25 am    Post subject: Reply with quote

Oops, I just forgot one thing... to upload the file!
Sorry for the inconvenience, and tell me what you think of my little library.
Thanks you for bringing this up, I should have tested my links.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 5298

PostPosted: Mon Aug 21, 2006 9:59 am    Post subject: Reply with quote



I tried it in Windows 2000 SP4. The script hinted me to put GDIPlus.dll in the Path.
Since I have WIN XP installed, I borrowed a copy of GDIPlus.dll and dropped it into the Scripts folder...

I tested with a BMP snapshot of my desktop 1024x768 file size: 2305 KB.
Oh my! Terrific speed ... I did not expect it to be fast! Shocked

I have to spend time with your code to understand the internals! How does this work fast?
Thanks for putting such a great effort .. and for sharing the wonderful code with us.

Quote:
I don't plan to extend much this library right now, but I am open to suggestions. I think it opens a whole world of image creation/alteration...


What would I ask? or What should I request?
One thing is missing in this forum for a long time...
Saving Clipboard Bitmap data to a file..
Maybe, this is too much to ask .. but it will definitely supplement.

Please consider ..

Regards, Smile
_________________
SKAN - Suresh Kumar A N
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6702
Location: France (near Paris)

PostPosted: Mon Aug 21, 2006 11:19 am    Post subject: Reply with quote

Goyyah wrote:
I have to spend time with your code to understand the internals! How does this work fast?
Easy: I let Windows (ie. the GDI+ DLL) to all the hard work! So it is as fast as a C program can be...

Goyyah wrote:
What would I ask? or What should I request?
Perhaps something like this Unicode Logo Generator... Yes, that's the kind of things that you can do with GDI+! And what I won't do, at least not soon...

Goyyah wrote:
One thing is missing in this forum for a long time...
Saving Clipboard Bitmap data to a file..
Excellent idea, I will consider it.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
robiandi



Joined: 08 Aug 2006
Posts: 50

PostPosted: Mon Aug 21, 2006 11:49 am    Post subject: Reply with quote

It works fine !!!
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10450

PostPosted: Mon Aug 21, 2006 3:56 pm    Post subject: Reply with quote

Great work. I went through a similar challenge when adding the GDIplus support to AutoHotkey (because the functions have to be called in a way similar to DllCall due to the absence of GDIplus on operating systems older than XP).

By the way, I think someone above mentioned something about needing the DLL on XP. However, any system running XP or later shouldn't need a GDIplus DLL because the system already has one.
Back to top
View user's profile Send private message Send e-mail
SKAN



Joined: 26 Dec 2005
Posts: 5298

PostPosted: Mon Aug 21, 2006 4:14 pm    Post subject: Reply with quote

Chris wrote:
I think someone above mentioned something about needing the DLL on XP. However, any system running XP or later shouldn't need a GDIplus DLL because the system already has one.


I was that someone above!

I tested in Window 2000 - SP4 & so had to borrow GDIplus.dll from Windows XP (which is also installed in my computer.)

I mentioned it to alert Windows 2000 users.

Regards, Smile


_________________
SKAN - Suresh Kumar A N
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6702
Location: France (near Paris)

PostPosted: Mon Aug 21, 2006 4:16 pm    Post subject: Reply with quote

Chris wrote:
I think someone above mentioned something about needing the DLL on XP.
You read too fast Wink It was on Win2k.
I rewrite part of the code to add flexibility to define the encoding parameters. But it is a nightmare, because MS doesn't clearly define what parameters each encoder accepts (it just shows how to query these parameters from the encoders, and give some examples).
It can also be used to get some stats on images, like dimensions or content of EXIF fields, but it doesn't seems straightforward either.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 5298

PostPosted: Mon Aug 21, 2006 4:29 pm    Post subject: Reply with quote

PhiLho wrote:
It can also be used to get some stats on images, like dimensions or content of EXIF fields, but it doesn't seems straightforward either.


Shocked EXIF! Oooh! Sounds pretty interesting .. Regards, Smile
_________________
SKAN - Suresh Kumar A N
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6702
Location: France (near Paris)

PostPosted: Tue Aug 22, 2006 11:56 am    Post subject: Reply with quote

OK, it was quite easy to add support to images on clipboard. File is updated, I give a small example.

Perhaps I should simplify a bit the interface. The GDIplus_GetEncoderCLSID function could be avoided by just providing the Mime type of the format to the functions. They would have to call internally the function to get the encoder CLSID each time, but I suppose it wouldn't be noticeable on a modern computer.
Likewise, calling GDIplus_InitEncoderParameters isn't very nice, but currently needed to allocate the right size of memory.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 5298

PostPosted: Tue Aug 22, 2006 3:24 pm    Post subject: Reply with quote

PhiLho wrote:
support to images on clipboard. File is updated, I give a small example.


Thanks for including support for Clipboard image data.

I downloaded the three .ahk's afresh as well as the example code.
Then took a snapshot of Destktop ( {PrintScreen} ) and tried the example - but I get an error Sad



However, I am able to paste the image in any Image editor!

Please look into this.

Regards, Smile

Edit: The first example also does not work for me. I get the following error:
Error in GdipCreateBitmapFromFile (2: InvalidParameter) 0
_________________
SKAN - Suresh Kumar A N
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6702
Location: France (near Paris)

PostPosted: Tue Aug 22, 2006 3:49 pm    Post subject: Reply with quote

Goyyah wrote:
I downloaded the three .ahk's afresh as well as the example code.
Then took a snapshot of Destktop ( {PrintScreen} ) and tried the example - but I get an error Sad
For some mysterious reason, the parameter to the GetClipboardData call went back to 8 (CF_DIB) instead of 2 (CF_BITMAP).
Well, I corrected this, it should work now, thanks for reporting.

Goyyah wrote:
The first example also does not work for me. I get the following error:
Error in GdipCreateBitmapFromFile (2: InvalidParameter) 0
Well, it still works for me...
You should try and change the tiffColorDepth value (if the problem comes from here, I haven't added an error locator... but I had similar problems here), maybe it depends on the image you chose to test.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 5298

PostPosted: Tue Aug 22, 2006 4:32 pm    Post subject: Reply with quote

Dear PhiLho, Smile

Thanks for the fast response.
Things are perfect now. Very Happy

However, Jpeg Image Quality is not satisfactory!

Quote:
jpegQuality = 3


What will be the range for above variable?
I tried 10 .. I think the compression is heavy with too much of artifacts. Rolling Eyes

What am I missing?

Regards, Smile

Edit: Oops sorry! I found that the range is 1-100
I suggest this: It will be better you change the value to 80 in you example.
_________________
SKAN - Suresh Kumar A N
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3, 4, 5, 6, 7  Next
Page 1 of 7

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group