Aus Zwischenablage jpg erstellen Topic is solved

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Thomas_82

Aus Zwischenablage jpg erstellen  Topic is solved

28 Mar 2024, 07:33

Hallo liebe AHK Gemeinde,

Ich bin neu in der Benutzung des AHK.
Bin echt begeistert davon wie nützlich es bei der Arbeit sein kann, schnell Menüs mit Shortcuts zu öffnen usw.

Ist es möglich mit AHK aus der Zwischenablage eine JPG-Datei zu erstellen?

Ich habe bei allen meinen Arbeits-PC das Problem, dass bei der Benutzung der Tastenkombination Windowstaste + Shift + S (Snipping Toll) die Benachrichtigung nicht kommt, mit der ich den Screenshot speichern kann.
Daher mein Gedanke, dass ich mit der Tastenkombi einen Bildschirmauschnitt in die Zwischenablage speichere und dann per AHK-Script eine Datei erstelle.

Ist dies möglich?

Vielen Dank im Voraus
Gruß Thomas
KHA
Posts: 403
Joined: 21 Aug 2018, 11:11

Re: Aus Zwischenablage jpg erstellen

29 Mar 2024, 06:41

Hi,
unter der Voraussetzung es wird AHK v1 benutzt.
Der Code ist von Teadrinker

Code: Select all

#Requires Autohotkey v1
#NoEnv
#SingleInstance Force


jpegFilePath := A_ScriptDir . "\Bild.jpeg" ; specify the file path you prefer
quality := 1 ; specify quality from 0 to 1, where 1 is 100%

hBitmap := GetBitmapFromClipboard()
SaveBitmapToJpeg(hBitmap, jpegFilePath, quality)
DllCall("DeleteObject", "Ptr", hBitmap)

GetBitmapFromClipboard() {
   static CF_BITMAP := 2, CF_DIB := 8, SRCCOPY := 0x00CC0020
   if !DllCall("IsClipboardFormatAvailable", "UInt", CF_BITMAP)
      throw "There is no image in the Clipboard"
   if !DllCall("OpenClipboard", "Ptr", 0)
      throw "OpenClipboard failed"
   hDIB := DllCall("GetClipboardData", "UInt", CF_DIB, "Ptr")
   hBM := DllCall("GetClipboardData", "UInt", CF_BITMAP, "Ptr")
   DllCall("CloseClipboard")
   if !hDIB
      throw "GetClipboardData failed"
   pDIB := DllCall("GlobalLock", "Ptr", hDIB, "Ptr")
   width := NumGet(pDIB + 4, "UInt")
   height := NumGet(pDIB + 8, "UInt")
   bpp := NumGet(pDIB + 14, "UShort")
   DllCall("GlobalUnlock", "Ptr", pDIB)

   hDC := DllCall("CreateCompatibleDC", "Ptr", 0, "Ptr")
   oBM := DllCall("SelectObject", "Ptr", hDC, "Ptr", hBM, "Ptr")

   hMDC := DllCall("CreateCompatibleDC", "Ptr", 0, "Ptr")
   hNewBM := CreateDIBSection(width, -height,, bpp)
   oPrevBM := DllCall("SelectObject", "Ptr", hMDC, "Ptr", hNewBM, "Ptr")
   DllCall("BitBlt", "Ptr", hMDC, "Int", 0, "Int", 0, "Int", width, "Int", height
      , "Ptr", hDC , "Int", 0, "Int", 0, "UInt", SRCCOPY)
   DllCall("SelectObject", "Ptr", hDC, "Ptr", oBM, "Ptr")
   DllCall("DeleteDC", "Ptr", hDC), DllCall("DeleteObject", "Ptr", hBM)
   DllCall("SelectObject", "Ptr", hMDC, "Ptr", oPrevBM, "Ptr")
   DllCall("DeleteDC", "Ptr", hMDC)
   Return hNewBM
}

CreateDIBSection(w, h, ByRef ppvBits := 0, bpp := 32) {
   hDC := DllCall("GetDC", "Ptr", 0, "Ptr")
   VarSetCapacity(BITMAPINFO, 40, 0)
   NumPut(40 , BITMAPINFO, 0)
   NumPut( w , BITMAPINFO, 4)
   NumPut( h , BITMAPINFO, 8)
   NumPut( 1 , BITMAPINFO, 12)
   NumPut(bpp, BITMAPINFO, 14)
   hBM := DllCall("CreateDIBSection", "Ptr", hDC, "Ptr", &BITMAPINFO, "UInt", 0
      , "PtrP", ppvBits, "Ptr", 0, "UInt", 0, "Ptr")
   DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
   return hBM
}

SaveBitmapToJpeg(hBitmap, destJpegFilePath, quality := 0.75) {
    static CLSID_WICImagingFactory  := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
         , IID_IWICImagingFactory   := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
         , GUID_ContainerFormatJpeg := "{19E4A5AA-5662-4FC5-A0C0-1758028E1057}"
         , WICBitmapIgnoreAlpha := 0x2, GENERIC_WRITE := 0x40000000, VT_R4 := 0x00000004
         , WICBitmapEncoderNoCache := 0x00000002, szPROPBAG2 := 24 + A_PtrSize*2

   VarSetCapacity(GUID, 16, 0)
   DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatJpeg, "Ptr", &GUID)
   IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
   Vtable( IWICImagingFactory    , CreateBitmapFromHBITMAP := 21 ).Call("Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapIgnoreAlpha, "PtrP", IWICBitmap)
   Vtable( IWICImagingFactory    , CreateStream            := 14 ).Call("PtrP", IWICStream)
   Vtable( IWICStream            , InitializeFromFilename  := 15 ).Call("WStr", destJpegFilePath, "UInt", GENERIC_WRITE)
   Vtable( IWICImagingFactory    , CreateEncoder           :=  8 ).Call("Ptr", &GUID, "Ptr", 0, "PtrP", IWICBitmapEncoder)
   Vtable( IWICBitmapEncoder     , Initialize              :=  3 ).Call("Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
   Vtable( IWICBitmapEncoder     , CreateNewFrame          := 10 ).Call("PtrP", IWICBitmapFrameEncode, "PtrP", IPropertyBag2)

   Vtable( IPropertyBag2         , CountProperties         :=  5 ).Call("UIntP", count)
   VarSetCapacity(arrPROPBAG2    , szPROPBAG2*count, 0)
   Vtable( IPropertyBag2         , GetPropertyInfo         :=  6 ).Call("UInt", 0, "UInt", count, "Ptr", &arrPROPBAG2, "UIntP", read)
   Loop % read
      addr := &arrPROPBAG2 + szPROPBAG2*(A_Index - 1)
   until StrGet(NumGet(addr + 8 + A_PtrSize)) = "ImageQuality" && found := true
   if found {
      VarSetCapacity(variant, 24, 0)
      NumPut(VT_R4, variant)
      NumPut(quality, variant, 8, "Float")
      Vtable( IPropertyBag2, Write := 4 ).Call("UInt", 1, "Ptr", addr, "Ptr", &variant)
   }
   Vtable( IWICBitmapFrameEncode , Initialize              :=  3 ).Call("Ptr", IPropertyBag2)
   Vtable( IWICBitmapFrameEncode , WriteSource             := 11 ).Call("Ptr", IWICBitmap, "Ptr", 0)
   Vtable( IWICBitmapFrameEncode , Commit                  := 12 ).Call()
   Vtable( IWICBitmapEncoder     , Commit                  := 11 ).Call()
   for k, v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IPropertyBag2, IWICStream, IWICBitmap, IWICImagingFactory]
      ObjRelease(v)
}

Vtable(ptr, n) {
   return Func("DllCall").Bind(NumGet(NumGet(ptr+0), A_PtrSize*n), "Ptr", ptr)
}

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 10 guests