Jump to content

GDIplus crashes without error on running function twice


corgano
 Share

Recommended Posts

This is a script that finds the black borders of an image. It accomplishes this by rotating the page so the side it wants to work on is on the top, measures down, and then rotates it back - until it stopped working.

When I run it the first time, it works and returns the correct value. However, when I run it for another side, autoit crashes without giving an error :/ The side I run first / second doesn't matter, even the same side running twice crashes it.  Any ideas?

#include <GDIPlus.au3>
#include <Array.au3>
; not sure if this one is needed
#include <WindowsConstants.au3>


_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($Jpg)

$Bottom = Image_getBlackBorder($hImage, "Bottom", $Threshold)
$Right = Image_getBlackBorder($hImage, "Right", $Threshold)
$Left = Image_getBlackBorder($hImage, "Left", $Threshold)
$Top = Image_getBlackBorder($hImage, "Top", $Threshold)


_GDIPlus_Shutdown()


Func Image_getBlackBorder($hImage, $sSide = "Top", $Threshold = 97.5 )
    Local $iRotateFlipType = SideGetIRF($sSide)
    _GDIPlus_ImageRotateFlip($hImage, $iRotateFlipType)

    Local $step, $iX, $iY, $count, $similarity, $Black[4] = ["000000","00","00","00"]
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage), $iWidth = _GDIPlus_ImageGetWidth($hImage)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)

    $iX = $iWidth/2
    $iY = 10

    ConsoleWrite($sSide&"   ")

    For $iSteps = 20 to 400 Step 20
        $CurrentStep = $iHeight*2/3/$iSteps

        $hPen = _GDIPlus_PenCreate("0xFF00FFFF", 3)
        _GDIPlus_GraphicsDrawLine($hGraphics, $iX-20, $iY, $iX - $iSteps, $iY, $hPen)
        _GDIPlus_PenDispose($hPen)

;~      ConsoleWrite($iY&" to "&$iHeight*2/3&" step "&$CurrentStep&"    "&$iHeight&@CRLF)
    For $iY = $iY to $iHeight*2/3 Step $CurrentStep

        $similarity = ColorCheckSim($Black, _GDIPlus_BitmapGetPixel($hImage, $iX, $iY))
        $temp = $similarity[0]-(100-(100-$Threshold)*2)
        If $temp > 10 then $temp = 10
        if $temp < 0 Then $temp = 0
        $hPen = _GDIPlus_PenCreate("0xFF" & valuetoredgreen(100-($temp*10) ), 3)
        _GDIPlus_GraphicsDrawLine($hGraphics, $iX+20, $iY, $iX + $iSteps, $iY, $hPen)
        _GDIPlus_PenDispose($hPen)
;~      If $sSide = "Bottom" Then ConsoleWrite("    "&$iY&" "&$similarity[0]&"  "&$temp&@CRLF)
        If $similarity[0] < $Threshold Then
            $iY -= $CurrentStep
            ExitLoop
        EndIf
    Next

    If $iY < 0 Then $iY = 0
;~  ConsoleWrite(@CRLF)
    Next


    _GDIPlus_ImageRotateFlip($hImage, mod(4-$iRotateFlipType,4))

    _GDIPlus_GraphicsDispose($hGraphics)

    ConsoleWrite($iY&@CRLF)
    Return $iY
EndFunc


Func valuetoredgreen($num)
    $red = Round(510 - (2.55 * $num * 2))
    $green = Round(2.55 * $num * 2)
    If $red > 255 Then $red = 255
    If $green > 255 Then $green = 255
;~  ConsoleWrite($num&" "&$red&"    "&$green&@CRLF)
    Return Hex($red, 2) & Hex($green, 2) & "00"
EndFunc   ;==>valuetoredgreen

;100 = same, 0 = completely different
Func ColorCheckSim($c1, $c2)
;~  ConsoleWrite($c1&"  "&$c2&@CRLF)
    Local $aDif[4], $a, $b
    For $i = 1 To 3
        $a = Dec(StringMid($c1, ($i * 2) - 1, 2))
        $b = Dec(StringMid($c2, ($i * 2) - 1, 2))
        $aDif[$i] = 100 - (Abs($a - $b) / 2.55)
;~      ConsoleWrite($i&"   "&$aDif[$i]&@CRLF)
    Next
;~  ConsoleWrite($aDif[1]&" "&$aDif[2]&"    "&$aDif[3]&@CRLF)
    $aDif[0] = Round(($aDif[1] + $aDif[2] + $aDif[3]) / 3, 2)
    Return $aDif
EndFunc   ;==>ColorCheckSim

Func ColorStringtoArray($Color)
    Local $aRet[4]
    $aRet[0] = $Color
    $aRet[1] = StringLeft($Color, 2)
    $aRet[2] = StringMid($Color, 3, 2)
    $aRet[3] = StringRight($Color, 2)
    Return $aRet
EndFunc

Func _GDIPlus_ImageRotateFlip($hImage, $iRotateFlipType)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipImageRotateFlip", "hwnd", $hImage, "int", $iRotateFlipType)

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_ImageRotateFlip


Func _GDIPlus_BitmapGetPixel($hImage, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hImage, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return Hex(DllStructGetData($tArgb, "Argb"), 6)
EndFunc   ;==>_GDIPlus_BitmapGetPixel
Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

I always keep looking into problems after I post them

I re-ran the script with a different set of images, it works flawlessly. Re-ran with the set I was working on, and it crashes at this function

Func _GDIPlus_BitmapGetPixel($hImage, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hImage, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return Hex(DllStructGetData($tArgb, "Argb"), 6)
EndFunc   ;==>_GDIPlus_BitmapGetPixel

note, this only happens the SECOND time the Image_getBlackBorder() function is called, and this passes ~fifty times from the first run, but the second time the Image_getBlackBorder() function is called it gets to the first _GDIPlus_BitmapGetPixel() and it fails. WHY? It just worked with the exact same image half a second ago, fifty times, without any issues! Why does autoit crash now?

And even stranger, I open the source image in MSPaint, re-save it, and the program runs without issue. This baffles me because:

1: If it was an issue with the image, why does the first call to Image_getBlackBorder() work and the second one doesn't???

2: If it is a coding issue then the first call shouldn't work either, but it does

I am severely confused. Is this a bug in autoit? In the GDI udf?

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

Seems like you are missing the appropriate calls to _GDIPlus_Startup and _GDIPlus_Shutdown.

Also, it's unclear where the script is crashing. Is it when you run the script a 2nd time or on your 2nd call to the Image_getBlackBorder function?

Lol I realized that, I had them in the main script, and copied the functions over. I must have forgot to add them, thanks :P

The script crashes on the second call to Image_getBlackBorder, inside the first call to _GDIPlus_BitmapGetPixel() as such

call Image_getBlackBorder() for top

It loops, using _GDIPlus_BitmapGetPixel() several times without crashing

Returns

call Image_getBlackBorder() for right this time

It gets to the loop, but hard crashes at the first _GDIPlus_BitmapGetPixel()

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
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
 Share

×
×
  • Create New...