swap_image_color

  • Hi Leute ich bräuchte mal wieder eure Hilfe, es geht mir darum in einem Bitmapobject einen gewissen Farbcode durch einen
    anderen zu ersetzen. Dazu habe ich schon eine Funktion geschrieben doch die ist mir viel zu langsam grade bei grossen Bildern.

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <Gdip.au3>
    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    $file = FileOpenDialog("Image select", @ScriptDir, "Images (*.jpg;*.bmp;*.png)", 1 + 2)
    If @error Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    $hBitmap = _swap_image_color($file,"0xFFFFFFFF","0xFFFEFFFF")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _swap_image_color($path,$searchcolor="0xFFFFFFFF",$swapcolor="0x00000000")
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($path)
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
    Local $d = $width*$height
    Local $xi=0,$yi=0
    Local $test = 0
    For $i=0 To $d
    $hc = _GDIPlus_BitmapGetPixel($hBitmap,$xi, $yi)
    If "0x"&Hex($hc) = $searchcolor Then
    _GDIPlus_BitmapSetPixel($hBitmap, $xi, $yi, $swapcolor)
    $test+=1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $xi += 1
    If $xi = $width Then
    $hc = _GDIPlus_BitmapGetPixel($hBitmap,$xi, $yi)
    If "0x"&Hex($hc) = $searchcolor Then
    _GDIPlus_BitmapSetPixel($hBitmap, $xi, $yi, $swapcolor)
    $test+=1
    EndIf
    $xi=0
    $yi+=1
    EndIf
    Next
    MsgBox(0,"",$test & @CRLF & $d & @CRLF & $yi & @CRLF & $xi)
    Return $hBitmap
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_ImageSaveToFile($hBitmap,@ScriptDir&"\Test.png")
    _GDIPlus_Shutdown()

    [/autoit]

    meine Frage gibts eine schnellere Variante ??

  • Hab was im Englischem Forum gefunden , falls es noch einen intressiert hier die Function :D

    Spoiler anzeigen
    [autoit]

    Func _ImageColorRegExpReplace($hImage, $iColSrch, $iColNew, $iCount = 0)
    Local $Reslt, $stride, $format, $Scan0, $iIW, $iIH, $hBitmap1
    Local $v_BufferA, $AllPixels, $sREResult1, $sResult

    [/autoit] [autoit][/autoit] [autoit]

    $iIW = _GDIPlus_ImageGetWidth($hImage)
    $iIH = _GDIPlus_ImageGetHeight($hImage)

    [/autoit] [autoit][/autoit] [autoit]

    $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iIW, $iIH, $GDIP_PXF32ARGB)

    [/autoit] [autoit][/autoit] [autoit]

    ; Locks a portion of a bitmap for reading or writing
    $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $iIW, $iIH, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)

    [/autoit] [autoit][/autoit] [autoit]

    ;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData($Reslt, "Scan0")

    [/autoit] [autoit][/autoit] [autoit]

    $v_BufferA = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0) ; Create DLL structure for all pixels
    $AllPixels = DllStructGetData($v_BufferA, 1)
    ;ConsoleWrite("$AllPixels, raw data, first 9 colours = " & StringRegExpReplace($AllPixels, "(.{98})(.*)", "\1") & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Searches on this string - $sREResult1 whch has the prefix "0x" removed and a space put between pixels 8 characters long.
    $sREResult1 = StringRegExpReplace(StringTrimLeft($AllPixels, 2), "(.{8})", "\1 ")
    ;ConsoleWrite("$sREResult1 first 9 colours = " & StringRegExpReplace($sREResult1, "(.{81})(.*)", "\1") & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    If StringInStr($iColNew, "0x") > 0 Then $iColNew = StringReplace($iColNew, "0x", ""); Remove "0x" not needed

    [/autoit] [autoit][/autoit] [autoit]

    ; StringRegExpReplace performed and white spaces removed
    $sResult = StringStripWS(StringRegExpReplace($sREResult1, $iColSrch, $iColNew, $iCount), 8)

    [/autoit] [autoit][/autoit] [autoit]

    ; Replace "0x" prefix and set modified data back to DLL structure, $v_BufferA
    DllStructSetData($v_BufferA, 1, "0x" & $sResult)
    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt) ; releases the locked region

    [/autoit] [autoit][/autoit] [autoit]

    Return $hBitmap1
    EndFunc ;==>_ImageColorRegExpReplace

    [/autoit]

    wenn jemand eine noch bessere Methode kennt immer her damit ansonsten begnüge ich mich damit :)