Convert Image from png to jpg

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Convert Image from png to jpg

Post by mickey12 » 19 May 2022, 11:29

Hi,
I want to convert the images from Png to Jpg and from 8k format to 4k is it something that is possible with Ahk.
Thanks


mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Re: Convert Image from png to jpg

Post by mickey12 » 22 May 2022, 01:25

Thanks I have looked to the link you have provided. I was able to download the code but some of the link were not working also I did not find much documentation as I new to coding I find it difficult for me but I find one more code that works for me https://github.com/iseahound/ImagePut by @iseahound . Thanks if anybody looking for same think they can check out these both converter.

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Convert Image from png to jpg

Post by teadrinker » 22 May 2022, 05:12

An option without external libraries:

Code: Select all

ConvertToJpeg(sourceImageFilePath, 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}"
         , GENERIC_READ := 0x80000000, GENERIC_WRITE := 0x40000000
         , WICDecodeMetadataCacheOnDemand := 0, 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)
   hr := Vtable( IWICImagingFactory , CreateDecoderFromFilename :=  3 ).Call("WStr", sourceImageFilePath, "Ptr", 0, "UInt", GENERIC_READ
                                                                           , "UInt", WICDecodeMetadataCacheOnDemand, "PtrP", IWICBitmapDecoder, "UInt")
   if (hr != 0) {
      ObjRelease(IWICImagingFactory)
      MsgBox, Unsupported file format
      Return
   }
   Vtable( IWICBitmapDecoder  , GetFrame                  := 13 ).Call("UInt", frameIdx := 0, "PtrP", IWICBitmapFrameDecode, "UInt")
   
   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", IWICBitmapFrameDecode, "Ptr", 0)
   Vtable( IWICBitmapFrameEncode , Commit      := 12 ).Call()
   Vtable( IWICBitmapEncoder     , Commit      := 11 ).Call()
   for k, v in [ IWICBitmapFrameEncode, IWICBitmapEncoder, IPropertyBag2
               , IWICStream, IWICBitmapFrameDecode, IWICBitmapDecoder, IWICImagingFactory ]
      ObjRelease(v)
}

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

mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Re: Convert Image from png to jpg

Post by mickey12 » 24 May 2022, 13:49

Hi @teadrinker,
I tried testing your code. I assume I have to replace sourceImageFilePath, destJpegFilePath. Is it like fullpath or just name of the file. Also i want to resize it to [4096 * 4096].
Thanks

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Convert Image from png to jpg

Post by teadrinker » 24 May 2022, 15:06

mickey12 wrote: I assume I have to replace sourceImageFilePath, destJpegFilePath
Nope, you haven't to replace anything. ConvertToJpeg() is a function, so you have to call it passing the real source image file path, the destination jpeg file path and the desired quality as parameters, like this:

Code: Select all

ConvertToJpeg(A_ScriptDir . "\test.png", A_ScriptDir . "\test.jpg", 0.5)

ConvertToJpeg(sourceImageFilePath, 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}"
         , GENERIC_READ := 0x80000000, GENERIC_WRITE := 0x40000000
         , WICDecodeMetadataCacheOnDemand := 0, 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)
   hr := Vtable( IWICImagingFactory , CreateDecoderFromFilename :=  3 ).Call("WStr", sourceImageFilePath, "Ptr", 0, "UInt", GENERIC_READ
                                                                           , "UInt", WICDecodeMetadataCacheOnDemand, "PtrP", IWICBitmapDecoder, "UInt")
   if (hr != 0) {
      ObjRelease(IWICImagingFactory)
      MsgBox, Unsupported file format
      Return
   }
   Vtable( IWICBitmapDecoder  , GetFrame                  := 13 ).Call("UInt", frameIdx := 0, "PtrP", IWICBitmapFrameDecode, "UInt")
   
   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", IWICBitmapFrameDecode, "Ptr", 0)
   Vtable( IWICBitmapFrameEncode , Commit      := 12 ).Call()
   Vtable( IWICBitmapEncoder     , Commit      := 11 ).Call()
   for k, v in [ IWICBitmapFrameEncode, IWICBitmapEncoder, IPropertyBag2
               , IWICStream, IWICBitmapFrameDecode, IWICBitmapDecoder, IWICImagingFactory ]
      ObjRelease(v)
}

Vtable(ptr, n) {
   return Func("DllCall").Bind(NumGet(NumGet(ptr+0), A_PtrSize*n), "Ptr", ptr)
}
mickey12 wrote: Also i want to resize it
You can use this function:

Code: Select all

ScaleImage(sourceImgFile, destImgFile, newWidth := 0, newHeight := 0) {
   static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
        , IID_IWICImagingFactory  := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
        , IID_IWICBitmapSource    := "{00000120-A8F2-4877-BA0A-FD2B6645FB94}"
        , WICDecodeMetadataCacheOnDemand := 0x0
        , WICBitmapEncoderNoCache        := 0x2
        , GENERIC_READ  := 0x80000000
        , GENERIC_WRITE := 0x40000000
        , WICBitmapInterpolationModeFant             := 0x3
        , WICBitmapInterpolationModeHighQualityCubic := 0x4
        , WICBitmapInterpolationMode := A_OSVersion ~= "^\d" ? WICBitmapInterpolationModeHighQualityCubic : WICBitmapInterpolationModeFant

   if !(newWidth || newHeight) {
      MsgBox, newWidth or newHeight must be specified
      Return
   }
   IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
   hr := Vtable( IWICImagingFactory , CreateDecoderFromFilename := 3 ).Call("WStr", sourceImgFile, "Ptr", 0, "UInt", GENERIC_READ
                                                                          , "UInt", WICDecodeMetadataCacheOnDemand, "PtrP", IWICBitmapDecoder)
   if (hr != 0) {
      ObjRelease(IWICImagingFactory)
      MsgBox, Unsupported file format
      Return
   }
   VarSetCapacity(GUID_ContainerFormat, 16)
   Vtable( IWICBitmapDecoder        , GetContainerFormat := 5 ).Call("Ptr", &GUID_ContainerFormat)
   hr := Vtable( IWICImagingFactory , CreateEncoder      := 8 ).Call("Ptr", &GUID_ContainerFormat, "Ptr", 0, "PtrP", IWICBitmapEncoder)
   if (hr != 0) {
      ObjRelease(IWICImagingFactory), ObjRelease(IWICBitmapDecoder)
      MsgBox, Unsupported file format
      Return
   }
   Vtable( IWICBitmapDecoder     , GetFrame           := 13 ).Call("UInt", frameIdx := 0, "PtrP", IWICBitmapFrameDecode)
   Vtable( IWICBitmapFrameDecode , GetSize            :=  3 ).Call("UIntP", width, "UIntP", height)
   Vtable( IWICImagingFactory    , CreateBitmapScaler := 11 ).Call("PtrP", IWICBitmapScaler)
   
   newWidth := newWidth ? newWidth : width*newHeight//height
   newHeight := newHeight ? newHeight : height*newWidth//width
   Vtable( IWICBitmapScaler   , Initialize             :=  8 ).Call("Ptr", IWICBitmapFrameDecode, "UInt", newWidth, "UInt", newHeight
                                                                                                , "UInt", WICBitmapInterpolationMode)
   Vtable( IWICImagingFactory , CreateStream           := 14 ).Call("PtrP", IWICStream)
   Vtable( IWICStream         , InitializeFromFilename := 15 ).Call("WStr", destImgFile, "UInt", GENERIC_WRITE)
      
   Vtable( IWICBitmapEncoder    , Initialize     :=  3 ).Call("Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
   Vtable( IWICBitmapEncoder    , CreateNewFrame := 10 ).Call("PtrP", IWICBitmapFrameEncode, "PtrP", 0)
   Vtable( IWICBitmapFrameEncode, Initialize     :=  3 ).Call("Ptr", 0)
   
   IWICBitmapSource := ComObjQuery(IWICBitmapScaler, IID_IWICBitmapSource)
   Vtable( IWICBitmapFrameEncode, WriteSource := 11 ).Call("Ptr", IWICBitmapSource, "Ptr", 0)
   Vtable( IWICBitmapFrameEncode, Commit      := 12 ).Call()
   Vtable( IWICBitmapEncoder    , Commit      := 11 ).Call()
   
   for k, v in [ IWICBitmapSource, IWICBitmapFrameEncode
               , IWICBitmapEncoder, IWICStream, IWICBitmapScaler
               , IWICBitmapFrameDecode, IWICBitmapDecoder, IWICImagingFactory ]
      ObjRelease(v)
}

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

mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Re: Convert Image from png to jpg

Post by mickey12 » 24 May 2022, 15:47

i am getting this error
image.png
image.png (3.93 KiB) Viewed 925 times

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Convert Image from png to jpg

Post by teadrinker » 24 May 2022, 15:53

Show your code.

mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Re: Convert Image from png to jpg

Post by mickey12 » 24 May 2022, 15:56

I Just copy paste your code

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, Force

ConvertToJpeg(%A_ScriptDir% . "\test.png", %A_ScriptDir% . "\test.jpg", 0.6) {
   static CLSID_WICImagingFactory   := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
         , IID_IWICImagingFactory   := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
         , GUID_ContainerFormatJpeg := "{19E4A5AA-5662-4FC5-A0C0-1758028E1057}"
         , GENERIC_READ := 0x80000000, GENERIC_WRITE := 0x40000000
         , WICDecodeMetadataCacheOnDemand := 0, 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)
   hr := Vtable( IWICImagingFactory , CreateDecoderFromFilename :=  3 ).Call("WStr", sourceImageFilePath, "Ptr", 0, "UInt", GENERIC_READ
                                                                           , "UInt", WICDecodeMetadataCacheOnDemand, "PtrP", IWICBitmapDecoder, "UInt")
   if (hr != 0) {
      ObjRelease(IWICImagingFactory)
      MsgBox, Unsupported file format
      Return
   }
   Vtable( IWICBitmapDecoder  , GetFrame                  := 13 ).Call("UInt", frameIdx := 0, "PtrP", IWICBitmapFrameDecode, "UInt")
   
   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", IWICBitmapFrameDecode, "Ptr", 0)
   Vtable( IWICBitmapFrameEncode , Commit      := 12 ).Call()
   Vtable( IWICBitmapEncoder     , Commit      := 11 ).Call()
   for k, v in [ IWICBitmapFrameEncode, IWICBitmapEncoder, IPropertyBag2
               , IWICStream, IWICBitmapFrameDecode, IWICBitmapDecoder, IWICImagingFactory ]
      ObjRelease(v)
}

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

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Convert Image from png to jpg

Post by teadrinker » 24 May 2022, 15:58

Nope, this is not my code. :) You musn't change the body of the function, you have to call it, like I showed in the previous post.

mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Re: Convert Image from png to jpg

Post by mickey12 » 24 May 2022, 16:12

yes it is working now but i am getting some warnings like--
image.png
image.png (25.23 KiB) Viewed 894 times
image.png
image.png (31.56 KiB) Viewed 894 times
image.png
image.png (28.65 KiB) Viewed 894 times
and some more like that.

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Convert Image from png to jpg

Post by teadrinker » 24 May 2022, 16:14

Just remove #Warn.

mickey12
Posts: 38
Joined: 28 Apr 2022, 19:36

Re: Convert Image from png to jpg

Post by mickey12 » 24 May 2022, 16:22

Just one more think Transparent png is being filled with white color in the background. Is it possible to fill that with black.

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Convert Image from png to jpg

Post by teadrinker » 24 May 2022, 16:37

I haven't found such an option. Maybe someone else can help.

User avatar
boiler
Posts: 16902
Joined: 21 Dec 2014, 02:44

Re: Convert Image from png to jpg

Post by boiler » 24 May 2022, 17:09

This is probably more involved than you were looking to take on, but you could try replacing the transparent pixels in the png image with opaque black (0xFF000000) using a modification to @Xtra's Gdip_FilterColor() function that replaces one color with another. It currently treats both the original and replacement colors as fully opaque, but you could modify the C code to replace any pixel's color whose highest order byte is less than 0xFF (i.e., has at least some transparency) with opaque black. If compiling C code isn't your thing, the same thing could be accomplished in AHK, but it would be significantly slower.

Post Reply

Return to “Ask for Help (v1)”