 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
PhiLho
Joined: 27 Dec 2005 Posts: 6702 Location: France (near Paris)
|
Posted: Fri Aug 18, 2006 4:58 pm Post subject: Image conversions and capturing with GDI+ |
|
|
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.
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 |
|
 |
robiandi
Joined: 08 Aug 2006 Posts: 50
|
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5298
|
Posted: Sun Aug 20, 2006 6:54 am Post subject: |
|
|
Dear PhiLho,
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 |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6702 Location: France (near Paris)
|
Posted: Mon Aug 21, 2006 8:25 am Post subject: |
|
|
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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5298
|
Posted: Mon Aug 21, 2006 9:59 am Post subject: |
|
|
 
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!
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,  _________________ SKAN - Suresh Kumar A N |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6702 Location: France (near Paris)
|
Posted: Mon Aug 21, 2006 11:19 am Post subject: |
|
|
| 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 |
|
 |
robiandi
Joined: 08 Aug 2006 Posts: 50
|
Posted: Mon Aug 21, 2006 11:49 am Post subject: |
|
|
| It works fine !!! |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Mon Aug 21, 2006 3:56 pm Post subject: |
|
|
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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5298
|
Posted: Mon Aug 21, 2006 4:14 pm Post subject: |
|
|
| 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,
_________________ SKAN - Suresh Kumar A N |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6702 Location: France (near Paris)
|
Posted: Mon Aug 21, 2006 4:16 pm Post subject: |
|
|
| Chris wrote: | | I think someone above mentioned something about needing the DLL on XP. | You read too fast 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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5298
|
Posted: Mon Aug 21, 2006 4:29 pm Post subject: |
|
|
| 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. |
EXIF! Oooh! Sounds pretty interesting .. Regards,  _________________ SKAN - Suresh Kumar A N |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6702 Location: France (near Paris)
|
Posted: Tue Aug 22, 2006 11:56 am Post subject: |
|
|
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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5298
|
Posted: Tue Aug 22, 2006 3:24 pm Post subject: |
|
|
| 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
However, I am able to paste the image in any Image editor!
Please look into this.
Regards,
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 |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6702 Location: France (near Paris)
|
Posted: Tue Aug 22, 2006 3:49 pm Post subject: |
|
|
| 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  | 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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5298
|
Posted: Tue Aug 22, 2006 4:32 pm Post subject: |
|
|
Dear PhiLho,
Thanks for the fast response.
Things are perfect now.
However, Jpeg Image Quality is not satisfactory!
What will be the range for above variable?
I tried 10 .. I think the compression is heavy with too much of artifacts.
What am I missing?
Regards,
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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|