GDI+ Bild-dreh UDF

  • Ich weiß, viele verstehen GDI+ erstmal nicht so ganz und wollen/können sich nicht so intensiv damit beschäftigen.
    Deswegen habe ich jetzt eine Funktion gebastelt (die leider nicht sehr schnell ist), die ein Bild dreht.
    Und auch Funktionen wie auf ein Bild eine Maske setzen sind dabei und ein paar Funktionen um Teile vom Bild mit Alpha zu transparentieren ( Ein paar Funktionen habe ich glaube ich schonmal vorgestellt, aber sie sind in der gleichen Datei :P )

    Spoiler anzeigen
    [autoit]


    #include-once
    #include <DLLshow.au3>
    #include <GDIP.au3>
    ;#test
    _GDIPlus_Startup()
    $bmp=_GDIPlus_BitmapCreateFromFile("zzz.bmp")
    $alpha=100
    $bmp=_BmpTEllipse($bmp,$alpha)
    _GDIPlus_Imageshow($bmp)
    _GDIPlus_BitmapDispose($bmp)
    $bmp=_GDIPlus_BitmapCreateFromFile("zzz.bmp")
    $bmp=_TBmpFromBmp($bmp,$alpha,0,10,-1,10)
    $bmp=_TBmpFromBmp($bmp,$alpha,0,30,-1,10)
    $bmp=_TBmpFromBmp($bmp,$alpha,0,50,-1,10)
    $bmp=_TBmpFromBmp($bmp,$alpha,0,70,-1,10)
    $bmp=_TBmpFromBmp($bmp,$alpha,0,90,-1,10)
    $bmp=_TBmpFromBmp($bmp,$alpha,10,0,10,-1)
    $bmp=_TBmpFromBmp($bmp,$alpha,30,0,10,-1)
    $bmp=_TBmpFromBmp($bmp,$alpha,50,0,10,-1)
    $bmp=_TBmpFromBmp($bmp,$alpha,70,0,10,-1)
    $bmp=_TBmpFromBmp($bmp,$alpha,90,0,10,-1)
    $bmp=_TBmpFromBmp($bmp,$alpha,110,0,10,-1)
    _GDIPlus_Imageshow($bmp)
    _GDIPlus_BitmapDispose($bmp)
    $bmp=_GDIPlus_BitmapCreateFromFile("zzz.bmp")
    $bmp=_TBmpFromBmpDll($bmp,$alpha)
    $bmp=_CreateTurnedImage($bmp,45)
    _GDIPlus_Imageshow($bmp)
    _GDIPlus_BitmapDispose($bmp)
    _GDIPlus_Shutdown()
    ;#

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

    Func _CreateTurnedImage($bmp,$winkel)
    if $bmp=0 then return 0
    Local $gra,$buffer,$backgra
    Local $matrix=_GDIPlus_MatrixCreate()
    Local $w,$h
    $w=_GDIPlus_ImageGetWidth($bmp)
    $h=_GDIPlus_ImageGetHeight($bmp)
    _GDIPlus_MatrixTranslate($matrix, $w/2, $h/2)
    $gra=_GDIPlus_ImageGetGraphicsContext($bmp)
    $buffer=_GDIPlus_BitmapCreateFromGraphics($w,$h,$gra)
    $backgra=_GDIPlus_ImageGetGraphicsContext($buffer)
    _GDIPlus_MatrixRotate($matrix,$winkel)
    _GDIPlus_GraphicsSetTransform($backgra, $matrix)
    $color=_getnotincolor($bmp,$w,$h)
    _GDIPlus_GraphicsClear($backgra,$color)
    _GDIPlus_GraphicsDrawImage($backgra,$bmp,-$w/2,-$h/2)
    _MaskImage($buffer,$color)
    _GDIPlus_GraphicsDrawImage($gra,$buffer,0,0)
    _GDIPlus_MatrixDispose($matrix)
    _GDIPlus_GraphicsDispose($backgra)
    _GDIPlus_BitmapDispose($buffer)
    _GDIPlus_GraphicsDispose($gra)
    Return $bmp
    EndFunc

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

    Func _MaskImage($bmp,$color="0xFF000000")
    If $bmp=0 Then Return 0
    Local $w,$h
    $w=_GDIPlus_ImageGetWidth($bmp)
    $h=_GDIPlus_ImageGetHeight($bmp)
    For $x=0 to $w
    For $y=0 to $h
    $farbe="0x"&Hex(_gdiplus_Bitmapgetpixel($bmp,$x,$y))
    if $farbe=$color Then _gdiplus_Bitmapsetpixel($bmp,$x,$y,"0x00"&StringRight($color,6))
    Next
    Next
    Return $bmp
    EndFunc

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

    Func _BmpTEllipse($bmp,$alpha=100,$px=0,$py=0,$width=-1,$height=-1)
    If $bmp=0 Then Return 0
    Local $w,$h
    $w=_GDIPlus_ImageGetWidth($bmp)-1
    $h=_GDIPlus_ImageGetHeight($bmp)-1
    If $width=-1 Then $width=$w
    If $height=-1 Then $height=$h
    Local $tmpbmp=_GDIPlus_BitmapCloneArea($bmp,0,0,$w,$h)
    Local $color
    $color=_getnotincolor($bmp,$w,$h)
    Local $gra=_GDIPlus_ImageGetGraphicsContext($bmp)
    Local $brush=_GDIPlus_BrushCreateSolid($color)
    _GDIPlus_GraphicsFillEllipse($gra,$px,$py,$width,$height,$brush)
    _GDIPlus_BrushDispose($brush)
    _GDIPlus_GraphicsDispose($gra)
    For $x=0 To $w
    For $y=0 To $h
    $hex="0x"&Hex(_gdiplus_Bitmapgetpixel($bmp,$x,$y))
    If $hex=$color Then
    $ncolor="0x"&Hex($alpha,2)&StringRight(Hex(_gdiplus_Bitmapgetpixel($tmpbmp,$x,$y)),6)
    _gdiplus_Bitmapsetpixel($bmp,$x,$y,$ncolor)
    EndIf
    Next
    Next
    _GDIPlus_BitmapDispose($tmpbmp)
    Return $bmp
    EndFunc

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

    Func _getnotincolor($bmp,$w,$h)
    Local $color,$farben[$w+1][$h+1]
    For $x=0 To $w
    For $y=0 To $h
    $farben[$x][$y]="0x"&Hex(_gdiplus_Bitmapgetpixel($bmp,$x,$y))
    Next
    Next
    $color="0xFF000000"
    For $b=0 to 255
    For $g=0 to 255
    For $r=0 to 255
    $isin=0
    For $x=0 To $w
    For $y=0 To $h
    If StringRight($farben[$x][$y],6)=Hex($r,2)&Hex($g,2)&Hex($b,2) Then $isin=1
    Next
    Next
    If $isin=0 Then
    $color="0xFF"&Hex($r,2)&Hex($g,2)&Hex($b,2)
    ExitLoop 3
    EndIf
    Next
    Next
    Next
    Return $color
    EndFunc

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

    Func _TBmpFromBmp($bmp,$alpha=100,$px=0,$py=0,$width=-1,$height=-1)
    If $bmp=0 Then Return 0
    Local $w=_GDIPlus_ImageGetWidth($bmp)
    Local $h=_GDIPlus_ImageGetHeight($bmp)
    If $height<>-1 Then $h=$height
    If $width<>-1 Then $w=$width
    For $x=$px To $w+$px
    For $y=$py To $h+$py
    $pixel=_gdiplus_Bitmapgetpixel($bmp,$x,$y)
    $hex=Hex($pixel)
    $npixel="0x"&Hex($alpha,2)&StringRight($hex,6)
    _gdiplus_Bitmapsetpixel($bmp,$x,$y,$npixel)
    Next
    Next
    Return $bmp
    EndFunc

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

    Func _TBmpFromBmpDll($bmp,$alpha=100,$altesweg=1)
    If $bmp=0 Then Return 0
    Local $dat=@TempDir&"\tmp.bmp"
    Local $clsid=_GDIPlus_EncodersGetCLSID("BMP")
    _GDIPlus_ImageSaveToFileEx($bmp,$dat,$clsid)
    If $altesweg=1 Then _GDIPlus_BitmapDispose($bmp)
    DllCall("transbitmapx86.dll","none","_BmpToTBmp","str",$dat,"int",$alpha,"str",$dat)
    Local $tbmp=_GDIPlus_BitmapCreateFromFile($dat)
    Return $tbmp
    EndFunc

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

    Func Diashow($img,$mswechsel=1000,$titel="",$x=-1,$y=-1)
    If Not IsArray($img) Then Return -1
    Local $frames=UBound($img,1)-1
    Local $frame=0
    Local $timer=TimerInit()
    Local $skill
    Local $wx,$wy
    If $x=-1 Then
    $x=_GDIPlus_ImageGetWidth($img[0])
    EndIf
    If $x>@DesktopWidth Then $x=@DesktopWidth
    If $y=-1 Then
    $y=_GDIPlus_ImageGetHeight($img[0])
    EndIf
    if $y>@DesktopHeight-50 Then $y=@DesktopHeight-50
    $wx=$x
    $wy=$y
    Local $gui=GUICreate($titel,$x,$y,Default,Default,BitOR(0x00C00000,0x00080000)) ;bitor($WS_CAPTION,$WS_SYSMENU)
    GUISetState(@SW_SHOW,$gui)
    Local $gra=_GDIPlus_GraphicsCreateFromHWND($gui)
    Local $buffer=_GDIPlus_BitmapCreateFromGraphics($wx,$wy,$gra)
    Local $backgra=_GDIPlus_ImageGetGraphicsContext($buffer)
    _GDIPlus_GraphicsSetSmoothingMode($backgra,2)
    While GUIGetMsg()<>-3 ;$GUI_EVENT_CLOSE
    _WinAPI_RedrawWindow($gui, "", "", 1280) ;$RDW_UPDATENOW + $RDW_FRAME
    If TimerDiff($timer)-$skill>=$mswechsel Then
    $skill=TimerDiff($timer)
    $frame+=1
    If $frame>$frames Then $frame=0
    EndIf
    _GDIPlus_GraphicsClear($backgra)
    _GDIPlus_GraphicsDrawImageRect($backgra,$img[$frame],0,0,$wx,$wy)
    _GDIPlus_GraphicsDrawImageRect($gra,$buffer,0,0,$wx,$wy)
    Sleep(10)
    WEnd
    _GDIPlus_GraphicsDispose($backgra)
    _GDIPlus_BitmapDispose($buffer)
    _GDIPlus_GraphicsDispose($gra)
    GUIDelete($gui)
    Return 1
    EndFunc

    [/autoit]

    Ich freue mich Kritik, Anregungen, usw.. :)

  • Ich hab auch mal sowas gemacht :). (Damals kannte ich die GDIP.au3 noch nicht)

    Spoiler anzeigen
    [autoit]

    Func _GDIPlus_RotateImage($hImage, $iAngle = 0)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(@error, 0, 0)
    Local $hImageGraphicsTmp = _GDIPlus_ImageGetGraphicsContext($hImage)
    Local $hBitmapReturn = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hImageGraphicsTmp)
    Local $hBitmapGraphicsTmp = _GDIPlus_ImageGetGraphicsContext($hBitmapReturn)

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

    Local $hRotateMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hRotateMatrix, $iWidth / 2, $iHeight / 2)
    _GDIPlus_MatrixRotate($hRotateMatrix, $iAngle)
    _GDIPlus_GraphicsSetTransform($hBitmapGraphicsTmp, $hRotateMatrix)

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

    _GDIPlus_GraphicsDrawImageRect($hBitmapGraphicsTmp, $hImage, - $iWidth / 2, - $iHeight / 2, $iWidth, $iHeight)

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

    _GDIPlus_GraphicsDispose($hImageGraphicsTmp)
    _GDIPlus_GraphicsDispose($hBitmapGraphicsTmp)
    _GDIPlus_ImageDispose($hImage)

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

    Return $hBitmapReturn
    EndFunc

    [/autoit]


    Allerdings finde ich es besser, die Rotationsmatrix direkt auf die Grafik anzuwenden in die man das Bild zeichnen möchte. :D
    Aber für Anfänger Top! :thumbup:

  • Bei mir ist eigentlich hautsächlich verändert, dass es aufs Bild gezeichnet wird und der Hintergrund der von Matrix auf dem Buffer bleiben würde transparent wird (leider erstellt Matrix dazu auchnoch blöde Linien)