Sign in to follow this  
Followers 0
ryadical

Multipage Tiff files with GDI+ and MPDF

3 posts in this topic

I am trying to convert multipage tiff files to PDF and the example script that comes with MPDF_UDF will only convert the first page. I started digging into the UDF and found that it uses GDI+ to work with the image files. I found an old post here: '?do=embed' frameborder='0' data-embedContent>> where someone stated that he created functions for the GDI udf that work with multipage tiff files but It looks like his submission was removed.

Can anyone tell me if there are GDI functions in the current AutoIT that work with multipage tiff files? I do not have a good understanding of image manipulation presently to write my own functions for it. I was going to start playing with the UDFs to see if I could get something working but it is tough since I can not find the documentation I need to move forward. At least if I understood why it does not work right now that might be a help.

Can anyone push me in the right direction as to how I would either fix GDI (if it is in fact broken) to support Multipage tiff files or manipulate the MPDF_UDF Image2PDF example to work with multipage tiffs?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Try this function:

;code by Eukalyptus
Func _GDIPlus_ImageLoadFromMultiPageImage($sPath)
    Local $hImage = _GDIPlus_ImageLoadFromFile($sPath)
    If @error Then Return SetError(1, 1, False)
    Local $iCount = _GDIPlus_ImageGetFrameDimensionsCount($hImage)
    If Not $iCount Then Return SetError(1, 2, False)
    Local $aList = _GDIPlus_ImageGetFrameDimensionsList($hImage)
    If @error Or Not IsArray($aList) Then Return SetError(1, 3, False)

    Local $iPixelFormat, $iImageW, $iImageH
    Local $aReturn[1], $iCnt = 0
    For $i = 1 To $aList[0]
        $iCount = _GDIPlus_ImageGetFrameCount($hImage, $aList[$i])
        For $j = 1 To $iCount
            _GDIPlus_ImageSelectActiveFrame($hImage, $aList[$i], $j)
            $iCnt += 1
            ReDim $aReturn[$iCnt + 1]
            $iPixelFormat = _GDIPlus_ImageGetPixelFormat($hImage)
            $iImageW = _GDIPlus_ImageGetWidth($hImage)
            $iImageH = _GDIPlus_ImageGetHeight($hImage)
            $aReturn[$iCnt] = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iImageW, $iImageH, $iPixelFormat)
        Next
    Next
    _GDIPlus_ImageDispose($hImage)
    $aReturn[0] = $iCnt
    Return $aReturn
EndFunc   ;==>_GDIPlus_ImageLoadFromMultiPageImage

Func _GDIPlus_ImageGetFrameDimensionsCount($hImage)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "handle", $hImage, "uint*", 0)
    If @error Then Return SetError(@error, @extended, -1)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_ImageGetFrameDimensionsCount

Func _GDIPlus_ImageGetFrameDimensionsList($hImage)
    Local $iI, $iCount, $tBuffer, $pBuffer, $aPropertyIDs[1], $aResult
    $iCount = _GDIPlus_ImageGetFrameDimensionsCount($hImage)
    If @error Then Return SetError(@error, @extended, -1)
    $tBuffer = DllStructCreate("byte[" & $iCount * 16 & "]")
    $pBuffer = DllStructGetPtr($tBuffer)
    $aResult = DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsList", "handle", $hImage, "ptr", $pBuffer, "int", $iCount)
    If @error Then Return SetError(@error, @extended, -1)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    ReDim $aPropertyIDs[$iCount + 1]
    $aPropertyIDs[0] = $iCount
    For $iI = 1 To $iCount
        $aPropertyIDs[$iI] = _WinAPI_StringFromGUID($pBuffer)
        $pBuffer += 16
    Next
    Return $aPropertyIDs
EndFunc   ;==>_GDIPlus_ImageGetFrameDimensionsList

Func _GDIPlus_ImageSaveAddImage($hImage, $hImageNew, $pParams)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAddImage", "handle", $hImage, "handle", $hImageNew, "ptr", $pParams)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_ImageSaveAddImage

Func _GDIPlus_ImageGetFrameCount($hImage, $sDimensionID)
    Local $tGUID, $pGUID, $aResult
    $tGUID = _WinAPI_GUIDFromString($sDimensionID)
    $pGUID = DllStructGetPtr($tGUID)
    $aResult = DllCall($ghGDIPDll, "int", "GdipImageGetFrameCount", "handle", $hImage, "ptr", $pGUID, "uint*", 0)
    If @error Then Return SetError(@error, @extended, -1)
    If $aResult[0] Then Return SetError(10, $aResult[0], -1)
    Return $aResult[3]
EndFunc   ;==>_GDIPlus_ImageGetFrameCount

Func _GDIPlus_ImageSelectActiveFrame($hImage, $sDimensionID, $iFrameIndex)
    Local $pGUID, $tGUID, $aResult
    $tGUID = DllStructCreate($tagGUID)
    $pGUID = DllStructGetPtr($tGUID)
    _WinAPI_GUIDFromStringEx($sDimensionID, $pGUID)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipImageSelectActiveFrame", "handle", $hImage, "ptr", $pGUID, "uint", $iFrameIndex)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_ImageSelectActiveFrame

It will return an array with bitmap handles.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

That seemed to do 99% of the trick. I was able to use it to modify the MPDF function to convert multipage tiff files to pdf. My only issue is that it looks like the array that your function returns is out of order. On the files I tested it on it returned pages 2-n and then page 1 at the end.  Any idea why?

[EDIT] 

I figured it out. _GDIPlus_imageSelectActiveFrame is 0 based. I just needed to change the second For loop in  _GDIPlus_ImageLoadFromMultiPageImage to start with 0 instead of 1 and take one away from the count.

For $i = 1 To $aList[0]
        $iCount = _GDIPlus_ImageGetFrameCount($hImage, $aList[$i])
        For $j = 0 To $iCount - 1
            _GDIPlus_ImageSelectActiveFrame($hImage, $aList[$i], $j)
Edited by ryadical

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0