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 Previous  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
Rhys



Joined: 17 Apr 2007
Posts: 706
Location: Florida

PostPosted: Mon Nov 05, 2007 3:48 pm    Post subject: Reply with quote

OK, I have another question about GDI - I see that you've included a very handy loadbitmapfromclipboard function. Is there a way to do the opposite?

I'd like to (in addition to saving a file to disk) give users the option to have the image they've just captured (usually a rectangle that is user defined or the size of the active window) be injected into their clipboard.

Many times people would rather just paste the image into an email rather than access Insert>Picture>Browse>Select File>Click OK...

Ideally, I'd like the encoded (jpg or png) file to be loaded into the clipboard, but the bmp would be OK if that's not possible.
_________________
[Join IRC!]
Back to top
View user's profile Send private message
Safeguard
Guest





PostPosted: Sun Feb 03, 2008 9:56 am    Post subject: Reply with quote

Code:



; Save to PNG

step = GDIplus_GetEncoderCLSID for PNG
If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_PNG) != 0)
   Goto GDIplusError

step = GDIplus_SaveImage for PNG
If (GDIplus_SaveImage(png, fileNameDestP, pngEncoder, noParams) != 0)
   Goto GDIplusError




I am experimenting with this wonderful code. May I ask please, I am trying to convert images to PNG, but I want to resize them. Can someone please explain how I can pass parameters into this, to resize a PNG, or explain how to use GDIplusWrapper.ahk + its dependencies, to re-scale images (i.e. from lets say an original size of 500x500 to a 125x125? Smile Best wishes, Safeguard
Back to top
Safeguard
Guest





PostPosted: Sun Feb 03, 2008 8:47 pm    Post subject: Reply with quote

Here is some of the code I am working with. I don't know if I have too much stuff going on. Basically, I want to convert any image type, GIF, JPG or PNG to a resized PNG with the best quality. I dunno where I am missing something, ... but if I uncomment the line in red, it certainly saves a thumbnail snapshot of the desktop. I want to be able to read in any image type, and do the same thing. Any clues??

Have a great day & thank you!! Smile

Code:


#Include GDIplusWrapper.ahk

fileNameOrig = OriginalImage.png
fileNameDestP = ResultImage.png

noParams = NONE





; ---------------------------------------
; TRYING TO LOAD MY ORIGINAL IMAGE IN HERE
;
; WHAT DO I NEED TO GET ANY IMAGE TYPE INPUTTED HERE? PNG/JPG/GIF :)

step = GDIplus_Start
If (GDIplus_Start() != 0)
   Goto GDIplusError

; Load image

step = GDIplus_LoadImage
If (GDIplus_LoadImage(hw_frame, fileNameOrig) != 0)
   Goto GDIplusError
GDIplus_GetImageDimension(hw_frame, w, h)
MsgBox %w% %h%

; ---------------------------------------


; --- TEST LINE THAT WORKS IF UNCOMMENTED

;WinGet, hw_frame, id, "Program Manager"   ; Desktop ?



  hdc_frame := DllCall( "GetDC", "uint",  hw_frame )
  hdc_frame_full := DllCall( "GetDC", "uint",  hw_frame )
  counter:=0   ; thumbnails
  counter_f:=0   ; fullscreens
  thumb_w:= 200
  thumb_h:= ceil( thumb_w * A_ScreenHeight / A_ScreenWidth ) ; keep screenratio
  use_antialize := 1
 

  ; buffer
  hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC"     , "uint", hdc_frame )
  hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame, "int", thumb_w, "int", thumb_h )
  r          := DllCall( "gdi32.dll\SelectObject"           , "uint", hdc_buffer, "uint", hbm_buffer )

  hdc_buffer_full := DllCall( "gdi32.dll\CreateCompatibleDC"     , "uint", hdc_frame_full )
  hbm_buffer_full := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame_full, "int", A_ScreenWidth, "int", A_ScreenHeight )
  r_full          := DllCall( "gdi32.dll\SelectObject"           , "uint", hdc_buffer_full, "uint", hbm_buffer_full )

  ; comment this line for speed but less quality
  if use_antialize = 1
    DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_buffer, "int", 4 )  ; Halftone better quality with stretch

 
  If (GDIplus_Start() != 0)
     Goto GDIplusError



; ---- IS THIS STEP NECESSARY? WANT BEST QUALITY
; ---- IS THIS STEP NECESSARY? WANT BEST QUALITY
; ---- IS THIS STEP NECESSARY? WANT BEST QUALITY
; ---- IS THIS STEP NECESSARY? WANT BEST QUALITY

  ; Copy BMP from DC

  DllCall( "gdi32.dll\StretchBlt"
          , "uint", hdc_buffer, "int", 0, "int", 0, "int", thumb_w, "int", thumb_h
          , "uint", hdc_frame,  "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight, "uint", 0x00CC0020 )

  DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer, uint, 0, uintp, bitmap )


  ; Save to PNG

  If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
     Goto GDIplusError

  If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
     Goto GDIplusError


   DllCall( "gdi32.dll\DeleteObject", "uint", hbm_buffer )
   DllCall( "gdi32.dll\DeleteDC"    , "uint", hdc_frame )
   DllCall( "gdi32.dll\DeleteDC"    , "uint", hdc_buffer )

   GDIplus_Stop()



GDIplusError:
MsgBox, SOMETHING IS WRONG
Return




thank you!!!!
Back to top
Safeguard
Guest





PostPosted: Mon Feb 04, 2008 11:42 pm    Post subject: Reply with quote

meep meep

Can this be done, or this just dreams and mist? Sad :/
Back to top
tic



Joined: 22 Apr 2007
Posts: 1332

PostPosted: Tue Feb 05, 2008 12:06 am    Post subject: Reply with quote

resize them to what size though Question Question
if theyre all different sizes
Back to top
View user's profile Send private message
Safeguard
Guest





PostPosted: Tue Feb 05, 2008 12:24 am    Post subject: Reply with quote

Well, that is what I am hoping for. A GDI function that might be able to take a fixed PNG (or other image type) at a 500x140 size {for instance}.... and be able to save it as a thumbnail PNG at 400x112. The input and output size would certainly be variable. Maybe something like this if current programming in this thread can work towards this goal would be awesome for me... Smile
Back to top
Guest






PostPosted: Tue Feb 05, 2008 1:47 am    Post subject: Reply with quote

Safeguard wrote:
Code:
GDIplusError:
MsgBox, SOMETHING IS WRONG
Return

...OMFG!...WORST...ERROR...MESSAGE...EVER!!!...come on!...how do you expect to debug it with THAT error message?...I haven't even looked into this script & I'm gonna guess what I think'll work...

Code:
#Include GDIplusWrapper.ahk

;//HERE ARE THE FILENAMES!!!
;//fileNameOrig=OriginalImage.png
File_Src=Image-Src.png

Random, r, 1000000, 9999999
;//fileNameDestP=ResultImage.png
File_Dest=Image-Dest-%r%.png
;//File_Dest=%A_Temp%\Image-Dest-%r%.png

;//comment out to keep same size
File_Dest_w:=125
File_Dest_h:=125

;//File_Dest_scalew:=.4
;//File_Dest_scaleh:=.4

;//File_Dest_h:=ceil(thumb_w*A_ScreenHeight/A_ScreenWidth)      ;//keep screenratio

;//wtf does this mean?...anti-alias?
;//use_antialize:=1
;//renamed to...
;//Use_HALFTONE=1

;//wtf does this do?...dumb name...
;//noParams=NONE
encoderParams=None

;//---------------------------------------
;//TRYING TO LOAD MY ORIGINAL IMAGE IN HERE
;//
;//WHAT DO I NEED TO GET ANY IMAGE TYPE INPUTTED HERE? PNG/JPG/GIF :)

step=GDIplus_Start
if (GDIplus_Start()!=0)
   Goto, GDIplusError

;//Load image
step=GDIplus_LoadImage
if (GDIplus_LoadImage(hw_frame, File_Src)!=0)
   Goto, GDIplusError
GDIplus_GetImageDimension(hw_frame, File_Src_w, File_Src_h)

msgbox, 64, ,
(LTrim
   File_Src_w(%File_Src_w%) File_Src_h(%File_Src_h%)
   File_Dest_w(%File_Dest_w%) File_Dest_h(%File_Dest_h%)
)

;//---------------------------------------

if (File_Dest_w="") {
   File_Dest_w:=File_Src_w
   if (File_Dest_scalew)
      File_Dest_w*=File_Dest_scalew
}
if (File_Dest_h="") {
   File_Dest_h:=File_Src_h
   if (File_Dest_scaleh)
      File_Dest_h*=File_Dest_scaleh
}
if (File_Src_w!=File_Dest_w || File_Src_h!=File_Dest_h) {
   if (method="" || method="GDI+") {
      ;//GdipGetImageThumbnail(
      ;//      GpImage *image, UINT thumbWidth, UINT thumbHeight,
      ;//      GpImage **thumbImage, GetThumbnailImageAbort callback, VOID * callbackData)
      DllCall("GDIplus\GdipGetImageThumbnail"
         , "UInt", bitmap, "UInt", File_Dest_w, "UInt", File_Dest_h
         , "UInt", bitmap_thumb, "UInt", 0, "UInt", 0)
   } else if (method="StretchBlt") {
      msgbox, 16, , StretchBlt NOT IMPLEMENTED YET!
      return
      ;// *** Note: this code won't work, it's not cleaned up yet!
      hdc_frame:=DllCall("GetDC", "UInt", hw_frame)
      ;///hdc_frame_full:=DllCall("GetDC", "UInt", hw_frame)

      ;//buffer
      hdc_buffer:=DllCall("gdi32.dll\CreateCompatibleDC", "UInt", hdc_frame)
      hbm_buffer:=DllCall("gdi32.dll\CreateCompatibleBitmap" , "UInt", hdc_frame, "Int", thumb_w, "Int", thumb_h)
      r:=DllCall("gdi32.dll\SelectObject", "UInt", hdc_buffer, "UInt", hbm_buffer)

      ;///hdc_buffer_full:=DllCall("gdi32.dll\CreateCompatibleDC", "UInt", hdc_frame_full)
      ;///hbm_buffer_full:=DllCall("gdi32.dll\CreateCompatibleBitmap" , "UInt", hdc_frame_full, "Int", A_ScreenWidth, "Int", A_ScreenHeight)
      ;///r_full:=DllCall("gdi32.dll\SelectObject", "UInt", hdc_buffer_full, "UInt", hbm_buffer_full)

      ;//comment this line for speed but less quality
      ;//if (use_antialize=1) {
      if (Use_HALFTONE=1) {
         ;//Halftone better quality with stretch
         HALFTONE=4
         DllCall("gdi32.dll\SetStretchBltMode", "UInt", hdc_buffer, "Int", HALFTONE)
      }

      if (GDIplus_Start()!=0)
         Goto, GDIplusError

      ;//---- IS THIS STEP NECESSARY? WANT BEST QUALITY

      ;//Copy BMP from DC
      ;//Damn it!...don't use magic numbers...use vars!!!...like this...
      SRCCOPY:=0x00CC0020
      DllCall("gdi32.dll\StretchBlt"
            , "UInt", hdc_buffer, "Int", 0, "Int", 0, "Int", thumb_w, "Int", thumb_h
            , "UInt", hdc_frame, "Int", 0, "Int", 0, "Int", A_ScreenWidth, "Int", A_ScreenHeight, "UInt", SRCCOPY)

      DllCall("GDIplus\GdipCreateBitmapFromHBITMAP", "UInt", hbm_buffer, "UInt", 0, "UIntP", bitmap_thumb)

      DllCall("gdi32.dll\DeleteObject", "UInt", hbm_buffer)
      DllCall("gdi32.dll\DeleteDC", "UInt", hdc_frame)
      DllCall("gdi32.dll\DeleteDC", "UInt", hdc_buffer)
   }
}

;//Save to PNG
if (GDIplus_GetEncoderCLSID(pngEncoder, "image/png")!=0)
   Goto, GDIplusError

if (GDIplus_SaveImage(bitmap_thumb, File_Dest, pngEncoder, encoderParams)!=0)
   Goto, GDIplusError

GDIplus_Stop()
return

GDIplusError:
msgbox, SOMETHING IS WRONG...really helpful error huh?
return

...ok sorry that's not tested...I'll test it later...
Back to top
Safeguard
Guest





PostPosted: Tue Feb 05, 2008 4:11 am    Post subject: Reply with quote

Thank you so much for taking a crack at this.

This code seems to bomb out at this part

Code:


if (GDIplus_SaveImage(bitmap_thumb, File_Dest, pngEncoder, encoderParams)!=0)
   Goto, GDIplusError

Back to top
Guest






PostPosted: Tue Feb 05, 2008 7:38 am    Post subject: Reply with quote

Tested & working!...

Code:
#Include GDIplusWrapper.ahk

;//File_Src=Image-Src.png
File_Src=Image-Src.jpg

Gosub, File_Src_SizeImage

;//comment both out to keep same size, leave one blank to auto-size
File_Dest_w:=319
;//File_Dest_h:=319

;//File_Dest_w:=150
;//File_Dest_h:=150

;//File_Dest_w:=ceil(File_Src_w*.5)
;//File_Dest_h:=ceil(File_Src_h*.5)

;//File_Dest_w:=ceil(File_Src_w/5)
;//File_Dest_h:=ceil(File_Src_h/5)

Gosub, File_Dest_SizeImage

Random, r, 1000000, 9999999
StringReplace, r, r, % 7-1, 7, a
File_Dest=Image-Dest-%File_Dest_w%x%File_Dest_h%-%r%.png
;//File_Dest=Image-Dest.png
;//File_Dest=%A_Temp%\Image-Dest-%r%.png

;//encoderParams=None

Gosub, ScaleAndSaveImage

msgbox, 64, ,
(LTrim
   File_Src(%File_Src%)
   File_Dest(%File_Dest%)

   File_Src_w(%File_Src_w%) File_Src_h(%File_Src_h%)
   File_Dest_w(%File_Dest_w%) File_Dest_h(%File_Dest_h%)
)
return

;//--------------------------------------
File_Src_SizeImage:
step=GDIplus_Start
if (GDIplus_Start()!=0)
   Goto, GDIplusError

;//Load image
step=GDIplus_LoadImage
if (GDIplus_LoadImage(bitmap, File_Src)!=0)
   Goto, GDIplusError
GDIplus_GetImageDimension(bitmap, File_Src_w, File_Src_h)
return

;//--------------------------------------
File_Dest_SizeImage:
if (File_Dest_w="") {
   if (File_Dest_h)
      File_Dest_w:=ceil(File_Dest_h*File_Src_w/File_Src_h)
   else File_Dest_w:=File_Src_w
}
;//File_Dest_w:=File_Src_w%File_Dest_w%
if (File_Dest_h="") {
   if (File_Dest_w)
      File_Dest_h:=ceil(File_Dest_w*File_Src_h/File_Src_w)
   else File_Dest_h:=File_Src_h
}
;//File_Dest_h:=File_Src_h%File_Dest_h%
return

;//--------------------------------------
ScaleAndSaveImage:
if (File_Src_w!=File_Dest_w || File_Src_h!=File_Dest_h) {
   if (method="" || method="GDI+") {
      ;//GdipGetImageThumbnail(
      ;//      GpImage *image, UINT thumbWidth, UINT thumbHeight,
      ;//      GpImage **thumbImage, GetThumbnailImageAbort callback, VOID * callbackData)
      ret:=DllCall("GDIplus\GdipGetImageThumbnail"
         , "UInt", bitmap, "UInt", File_Dest_w, "UInt", File_Dest_h
         , "UInt *", bitmap_thumb, "UInt", 0, "UInt", 0)
      if (ret!=0) {
         msgbox, 16, , GdipGetImageThumbnail: ret(%ret%) A_LastError(%A_LastError%) Errorlevel(%Errorlevel%)
         Goto, GDIplusError
      }
   } else if (method="StretchBlt") {
      msgbox, 16, , StretchBlt NOT IMPLEMENTED YET!
      return
   }
} else bitmap_thumb:=bitmap

;//Save to PNG
if (GDIplus_GetEncoderCLSID(pngEncoder, "image/png")!=0)
   Goto, GDIplusError

if (GDIplus_SaveImage(bitmap_thumb, File_Dest, pngEncoder, encoderParams)!=0)
   Goto, GDIplusError

GDIplus_Stop()
return

;//--------------------------------------
GDIplusError:
;//msgbox, SOMETHING IS WRONG...really helpful error huh?
if (#GDIplus_lastError!="")
   msgbox, 16, GDIplus Test, Error in %#GDIplus_lastError% (at %step%)
return
Back to top
Safeguard
Guest





PostPosted: Tue Feb 05, 2008 9:20 am    Post subject: Reply with quote

Bravo! Very Happy Smile

But may I ask, I seem to get all general image input types to work with great quality, ... except JPG seems to have quality issues. It only becomes apparent if the image is larger than a thumbnail, ... so for instance a 700x700 .JPG reduced to 400x400 actually looks very very blurry Sad

Do you know why this for some reason is happening? I tested on two different machines with same result. Have a great day.

Best regards, Safeguard.
Back to top
grupo
Guest





PostPosted: Tue Feb 05, 2008 3:08 pm    Post subject: Reply with quote

Reading your post (http://www.autohotkey.com/forum/topic28211.html&sid=708822d38514a38883076498758d3c4c) in the ask for help section I noticed that you will try to use it for commercial purposes.
Do you mean "sell" the script?
If so, do you really want to sell someone else's work??
Back to top
Safeguard
Guest





PostPosted: Tue Feb 05, 2008 4:39 pm    Post subject: Reply with quote

Good question, though, separately the scripts in this forum are free and fair game to be incorporated into products and (be resold) for profit. Otherwise, do (or you should not) post in this forum. Smile

My aim is to not "sell" this script however, if you mean verbatim like it is now. Is that what you mean?

BTW, I hope you can fix the issue from the JPG. Is that of a concern? Smile
Back to top
Safeguard
Guest





PostPosted: Tue Feb 05, 2008 10:21 pm    Post subject: Reply with quote

Hi Grupo -- I presume you are Guest, and with sysop privileges to see peoples IP addresses...

anyway, I figured out a different solution, but thank you all the same for the concept. I think it was wrong to suggest I am selling Scripts... which I do not do and not to be taken out of context, ... yes, selling Scripts as is would be sort of unethical.... however, if nobody who shares, combines ideas, published updates, fixes etc... to the many scripts on here... then nobody could benefit.... just as the next person who might find this thread might be helped or not. Anyway, sorry for rant and thank you very much for your time.
Back to top
grupo
Guest





PostPosted: Tue Feb 05, 2008 11:01 pm    Post subject: Reply with quote

I am not "this guest" and did not see your IP address.
Also I did not suggest anything,I was asking a question.
Back to top
tic



Joined: 22 Apr 2007
Posts: 1332

PostPosted: Wed Feb 06, 2008 1:02 am    Post subject: Reply with quote

out of principle i will not help guest accounts. i think it is a sly way of posting
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 Previous  1, 2, 3, 4, 5, 6, 7  Next
Page 6 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