Aus Zwischenablage jpg erstellen Topic is solved

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Thomas_82

Aus Zwischenablage jpg erstellen  Topic is solved

Post by Thomas_82 » 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: 408
Joined: 21 Aug 2018, 11:11

Re: Aus Zwischenablage jpg erstellen

Post by KHA » 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)
}

Post Reply

Return to “Ich brauche Hilfe”