Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Clipboard as jpeg?



  • Please log in to reply
12 replies to this topic
grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

Hi all,

 

I 'm new to Ahk. I have compiled a script that sends CTRL+C to an image application, which in turn copies the image viewed to the clipboard.

However, as i found out, the image exists in the clipboard in both .bmp and .jpg format. Is there any way that i could manipulate the clipboard in order to delete the .bmp file and just leave the .jpg there?

 

thanks



grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

anyone?



Jack Dunning
  • Members
  • 217 posts
  • Last active: Nov 11 2015 08:40 PM
  • Joined: 08 Apr 2013

As I understand it, the Windows Clipboard automatically stores data in multiple formats depending upon the source. When pasting into an application, the application runs through the Clipboard list and takes the first one it recognizes--defaulting to bitmap for images. That means both the original application (copy) and the target application (paste) affects the result. I don't know how to manipulate how Clipboard does its various conversions. I think many may not understand why you're seeing two different formats in the Clipboard when most viewers will only show one image. We rarely think about the format of an image in Clipboard, since all the conversions are transparent. I think the problem may be in your applications and not the Clipboard. Of course, I'm frequently wrong.

 

See this explanation.


I currently do a regular blog for AutoHotkey beginners and have posted a number of AutoHotkey help pages at ComputorEdge.com. As I learn, I pass it on.

 

AutoHotkey scripts and apps for beginners and more ideas.


grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

thanks for replying Jack

 

The source application containing images is PmsDview, which is a medical viewer for Dicoms. It has a built-in function, with CTRL+C, that converts the DICOM to bmp / jpg and stores it to the clipboard.

The target application is a database created in Filemaker Pro v12. I 'm using the paste function to get the windows clipboard data, but for some reason, FM gets two formats of the image through paste and stores them both.  There is no way to manipulate this from inside FM.

 

Autohotkey sends ctrl+c to the 1st app and then paste to the 2nd, essentialy moving the images viewed to the database, automatically converting them in a different format.

 

I have found some Autohotkey scripts that utilise setClipboarddata/getClipboarddata functions, but I don't know how to transform them to something useful.

 

The part on the link you posted : "...Assuming the application finds a format it can use, it will then call GetClipboardData with the desired format identifier as a parameter to get a handle to the data...." sounds like a good start. i.e. : the Ahk script copies image to clipboard with ctrl+[key], then getsclipboarddata (jpeg format only) in a variable, then clears all clipboard and pastes back the jpeg format to clipboard through the variable.

 

Do you think that something like this can be done in Autohotkey?



Jack Dunning
  • Members
  • 217 posts
  • Last active: Nov 11 2015 08:40 PM
  • Joined: 08 Apr 2013

I would guess that there is a way to do it, but it's beyond my level of expertise. I would probably try something like saving the Clipboard image to a file first then inserting the image from the file. This thread looks like it has some potential, but to tell the truth it's all a little too much for me at this point.


I currently do a regular blog for AutoHotkey beginners and have posted a number of AutoHotkey help pages at ComputorEdge.com. As I learn, I pass it on.

 

AutoHotkey scripts and apps for beginners and more ideas.


grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

thanks again for the input Jack. The scripts in the link are too advanced for me to understand.

 

i did a lot of searching and came up with something, that unfortunately, doesn't work :(

 

it's like :

 

-script sends ctrl+c----image info is copied to clipboard

.....

image := DllCall("GetClipboardData", "Uint", "image/jpeg") ; copy jpeg image from clipboard to image variable
sleep 500
clipboard = ; empty clipboard
sleep 500
DllCall("SetClipboardData", "Uint", image) ;  paste jpeg image to clipboard
sleep 500

....

-script sends ctrl+v to target program

 

I 'm probably getting the syntax in the DllCalls wrong.

 

Any help from the experienced guys in DllCall functions?



noname
  • Members
  • 650 posts
  • Last active:
  • Joined: 12 Nov 2011

You could try to get the bitmap,clear the clipboard and set it again in the hope only one format is left.

 

You need Tic's gdip library gdip.ahk for the functions used in the following code.


;download Tic's library gdip.ahk from here http://www.autohotkey.com/forum/topic32238.html 
;and put it in same directory as this code (or standard library dir)

#Include  gdip.ahk




f4::
If !pToken := Gdip_Startup()
  {
    MsgBox, 48, gdiplus Error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
    ExitApp
  }
pBitmap:=Gdip_CreateBitmapFromClipboard()

;sFile=%a_scriptdir%\clipboard.jpg     ;just for testing save image to file
Gdip_SaveBitmapToFile(pBitmap, sFile)
clipboard=                            ;clear clipboard
sleep 1000
Gdip_SetBitmapToClipboard(pBitmap)
msgbox done
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

If you have the latest version of ahk 1.1 ( see ahkscript.org) you can take a look at what format is on the clipboard as found by windows,as there are also customized formats it can be misleading ......



;download Tic's library from here http://www.autohotkey.com/forum/topic32238.html 
#Include  gdip.ahk

msgbox %a_ahkversion%  

data=
(
CF_TEXT|1
CF_BITMAP|2
CF_METAFILEPICT|3
CF_SYLK|4
CF_DIF|5
CF_TIFF|6
CF_OEMTEXT|7
CF_DIB|8
CF_PALETTE|9
CF_PENDATA|10
CF_RIFF|11
CF_WAVE|12
CF_UNICODETEXT|13
CF_ENHMETAFILE|14
CF_FILES|15
CF_LOCALE|16
CF_DIBV5|17
)
global cf_par:={}
loop,parse,data,`n
cf_par[A_Index]:=regexreplace(A_LoopField,"\|.*$")

msgbox % GetClipboardFormat()
return


;this will get the image and save it to file and set it back
f4::
If !pToken := Gdip_Startup()
  {
    MsgBox, 48, gdiplus Error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
    ExitApp
  }
pBitmap:=Gdip_CreateBitmapFromClipboard()

sFile=%a_scriptdir%\clipboard.jpg
Gdip_SaveBitmapToFile(pBitmap, sFile)
clipboard=
sleep 1000
Gdip_SetBitmapToClipboard(pBitmap)
msgbox done
return



GetClipboardFormat(){
	Critical, On

 	DllCall("OpenClipboard")
 	while c := DllCall("EnumClipboardFormats","Int",c?c:0)
		x .= cf_par[c] "`n"
	DllCall("CloseClipboard")
  return x
}

winXP  and ahk unicode


grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

Hi NoName,

 

I tried the script and still have the same problem. 2 copies of the file. I think that the issue is due to the fact that the clipboard objects are not named (or don't have a source dir). Whenever I try to copy---paste from a known picture in a directory, I get one item with the paste function.

 

So the workaround should be as Jack initially suggetsted : to save the jpeg in a directory (the scriptdir you included in your script works fine when tested) and then copy that particular file back in the clipboard.

 

How should I modify your script in order to achieve this? (Preferably each saved object should have a timestamp number in order to avoid pasting multiple objects as "clipboard-1, clipboard-2, etc). I tried the FileRead function with *c , but didn't work.

 

pBitmap:=Gdip_CreateBitmapFromClipboard()

sFile=%a_scriptdir%\clipboard.jpg ;just for testing save image to file
Gdip_SaveBitmapToFile(pBitmap, sFile)
clipboard= ;clear clipboard             
sleep 1000
Gdip_SetBitmapToClipboard(pBitmap)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

 

thanks for your input.



noname
  • Members
  • 650 posts
  • Last active:
  • Joined: 12 Nov 2011
✓  Best Answer

I cannot see that there is a difference between getting the bitmap and setting it in a clean clipboard or  to saving it first and setting it back. :)

;this will get the image and save it to file and set it back
f4::
If !pToken := Gdip_Startup()
  {
    MsgBox, 48, gdiplus Error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
    ExitApp
  }
pBitmap:=Gdip_CreateBitmapFromClipboard()
time_stamp:=a_now
sFile=%a_scriptdir%\%time_stamp%.jpg
Gdip_SaveBitmapToFile(pBitmap, sFile)
clipboard=
sleep 1000
pBitmap_new:=Gdip_CreateBitmapFromFile(sFile)
Gdip_SetBitmapToClipboard(pBitmap_new)
msgbox done

;cleanup

Gdip_DisposeImage(pBitmap)
Gdip_DisposeImage(pBitmap_new)
;filedelete , %sFile%  ; if no files are needed
Gdip_Shutdown(pToken)
return

winXP  and ahk unicode


grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

well, as you guessed, it still doesn't do the trick. I 'm getting 2 file copies. After messing around for hours, i think there is another solution. I could manipulate the target software to insert a file from a pasted-through-the-clipboard url. This will definitely not lead to 2 copies.

 

so the script should instead initially save a jpg image to the script directory (as is already doing) and then paste the url of the file into the clipboard (no need for the other steps, such as clearing clip, and pasting back; presuming that the clipboard contents will be replaced by the final paste step of the url).

 

The code for pasting a url from a file in the clipboard has been published by Lexikos :

http://www.autohotke...-the-clipboard/

 

but I 'm having trouble integrating the two scripts.

 

again thanks a lot for taking the time to help



noname
  • Members
  • 650 posts
  • Last active:
  • Joined: 12 Nov 2011

I have a bad feeling about this..... :(

 

Anyway here is the script ,when the url is put on the clipboard the only way i have been able to test if it works is by using the paste command in explorer,it adds the file .

(or using the code i gave in the first post using getclipformat it returns CF-Files.

 

I only tried it with the latest ahk version (unicode) on winXP

 

Best of luck!





;this will get the image and save it to file and set it back
f4::
If !pToken := Gdip_Startup()
  {
    MsgBox, 48, gdiplus Error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
    ExitApp
  }
pBitmap:=Gdip_CreateBitmapFromClipboard()
time_stamp:=a_now
sFile=%a_scriptdir%\%time_stamp%.jpg
Gdip_SaveBitmapToFile(pBitmap, sFile)
clipboard=
sleep 1000
FileToClipboard(sFile,"copy")
msgbox done

;cleanup

Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

FileToClipboard(PathToCopy,Method="copy")
   {
   FileCount:=0
   PathLength:=0

   ; Count files and total string length
   Loop,Parse,PathToCopy,`n,`r
      {
      FileCount++
      PathLength+=StrLen(A_LoopField)
      }

   pid:=DllCall("GetCurrentProcessId","uint")
   hwnd:=WinExist("ahk_pid " . pid)
   ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
   hPath := DllCall("GlobalAlloc","uint",0x42,"uint",20 + (PathLength + FileCount + 1) * 2,"UPtr")
   pPath := DllCall("GlobalLock","UPtr",hPath)
   NumPut(20,pPath+0),pPath += 16 ; DROPFILES.pFiles = offset of file list
   NumPut(1,pPath+0),pPath += 4 ; fWide = 0 -->ANSI,fWide = 1 -->Unicode
   Offset:=0
   Loop,Parse,PathToCopy,`n,`r ; Rows are delimited by linefeeds (`r`n).
      offset += StrPut(A_LoopField,pPath+offset,StrLen(A_LoopField)+1,"UTF-16") * 2

   DllCall("GlobalUnlock","UPtr",hPath)
   DllCall("OpenClipboard","UPtr",hwnd)
   DllCall("EmptyClipboard")
   DllCall("SetClipboardData","uint",0xF,"UPtr",hPath) ; 0xF = CF_HDROP

   ; Write Preferred DropEffect structure to clipboard to switch between copy/cut operations
   ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
   mem := DllCall("GlobalAlloc","uint",0x42,"uint",4,"UPtr")
   str := DllCall("GlobalLock","UPtr",mem)

   if (Method="copy")
      DllCall("RtlFillMemory","UPtr",str,"uint",1,"UChar",0x05)
   else if (Method="cut")
      DllCall("RtlFillMemory","UPtr",str,"uint",1,"UChar",0x02)
   else
      {
      DllCall("CloseClipboard")
      return
      }

   DllCall("GlobalUnlock","UPtr",mem)

   cfFormat := DllCall("RegisterClipboardFormat","Str","Preferred DropEffect")
   DllCall("SetClipboardData","uint",cfFormat,"UPtr",mem)
   DllCall("CloseClipboard")
   return
   }



winXP  and ahk unicode


grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

double post



grouper
  • Members
  • 10 posts
  • Last active: Nov 03 2014 08:16 PM
  • Joined: 30 Oct 2014

Unfortunately, the last script didn't work (i did not get any result in the clipboard), but i finally managed to get it to work in a simpler way :
by adding Clipboard = %a_scriptdir%\%time_stamp%.jpg at the end.
 
here's the final code in case anyone's interested :

 

;download Tic's library gdip.ahk from here http://www.autohotke...topic32238.html
;and put it in same directory as this code (or standard library dir)

#Include gdip.ahk

;this will get an image from the clipboard and save it to file as jpeg with a timestap for a name;
; finally it will leave the clipboard with just the filepath pasted in

f4::
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus Error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
pBitmap:=Gdip_CreateBitmapFromClipboard()
time_stamp:=a_now
sFile=%a_scriptdir%\%time_stamp%.jpg
Gdip_SaveBitmapToFile(pBitmap, sFile)
clipboard=
sleep 1000
pBitmap_new:=Gdip_CreateBitmapFromFile(sFile)
Gdip_SetBitmapToClipboard(pBitmap_new)


;cleanup

Gdip_DisposeImage(pBitmap)
Gdip_DisposeImage(pBitmap_new)
Gdip_Shutdown(pToken)

; copy filepath to clipboard
Clipboard = %a_scriptdir%\%time_stamp%.jpg
sleep 100
;filedelete , %sFile% ; if no files are needed
return

 

thanks a lot for your help noname, this is all possible because of your contributions. :)

 

cheers

 

sorry about the code format, i don't know how to use the forum options properly.