GDI+ - ungewollter Farbverlauf beim Strecken von Bildern

  • Hi,

    wie der Titel schon sagt, wollte ich mit GDI+ Bilder strecken,
    nur leider wird es zum Ende hin immer transparenter.

    Da die Fenstergröße variabel ist, kann ich die Bilder auch nicht in festen Größen nutzen,
    und GuiCtrlCreatePic ist für das was ich vorhab zu langsam :(

    Kennt ihr ne Möglichkeit das Problem zu umgehen?

    Danke, schonmal!!!

  • wieso ist guictrlcreatepic zu langsam?

    die bilder könnte man zumindest an die guibreite schön anpassen...
    weiß nich ob dus schon kennst, oder ob es dir hilft, aber ich stells trotzdem mal rein (siehe spoiler)
    mit GDI+ kenn ich mich leider viel zu wenig aus, da wirste auf die Guru's warten müssen ^^

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

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

    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Form1", 205, 681, 193, 125, $WS_SIZEBOX+$WS_SYSMENU)
    $Pic1 = GUICtrlCreatePic("C:\Dokumente und Einstellungen\Michi\Desktop\Messager.bmp", 0, 0, 205, 681)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Pic1
    EndSwitch
    WEnd

    [/autoit]
  • probiere mal, vor dem Skalieren eine andere Interpolationsmethode aus ;)

    Spoiler anzeigen
    [autoit]

    Global Const $InterpolationModeInvalid = -1 ;$QualityModeInvalid
    Global Const $InterpolationModeDefault = 0 ;$QualityModeDefault
    Global Const $InterpolationModeLowQuality = 1;$QualityModeLow
    Global Const $InterpolationModeHighQuality = 2 ;$QualityModeHigh
    Global Const $InterpolationModeBilinear = 3
    Global Const $InterpolationModeBicubic = 4
    Global Const $InterpolationModeNearestNeighbor = 5
    Global Const $InterpolationModeHighQualityBilinear = 6
    Global Const $InterpolationModeHighQualityBicubic = 7

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

    ; Sets the interpolation mode of this Graphics object. The interpolation mode determines the algorithm that is used when images are scaled or rotated.
    ; $pGraphics - [in] Pointer to the Graphics object.
    ; $iInterpolMode - [in] Element of the InterpolationMode enumeration that specifies the interpolation mode.
    Func _GdipSetInterpolationMode($pGraphics, $iInterpolMode)
    ;Author: Prog@ndy
    Local $aResult = DllCall($ghGDIPdll, "int", 'GdipSetInterpolationMode', 'ptr', $pGraphics, 'dword', $iInterpolMode)
    If @error Then Return SetError(1,0,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
    EndFunc

    [/autoit]
  • Danke euch beiden.
    Mit Schnitzels Methode geht es ohne das Bild jedesmal neu zu laden :thumbup:

    @Prog@ndy: klappt leider nicht, mich würde aber trotzdem mal interessieren ob und wie das in GDI umsetzbar ist

    Beispiel:

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>

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

    $hGui = GUICreate("Test", 150,100)
    _GDIPlus_Startup()
    $hGDI = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $Pic = _GDIPlus_ImageLoadFromFile(@ScriptDir&"\FrameTop.png")
    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixScale($hMatrix, 150, 1)
    _GdipSetInterpolationMode($hGDI, 7)
    _GDIPlus_GraphicsSetTransform($hGDI, $hMatrix)

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

    GUISetState()
    _GDIPlus_GraphicsDrawImage($hGDI,$Pic,0,0)
    Sleep(5000)

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

    Func _GdipSetInterpolationMode($pGraphics, $iInterpolMode)
    ;Author: Prog@ndy
    Local $aResult = DllCall($ghGDIPdll, "int", 'GdipSetInterpolationMode', 'ptr', $pGraphics, 'dword', $iInterpolMode)
    If @error Then Return SetError(1,0,0)
    Return SetError($aResult[0], 0, $aResult[0]=0)
    EndFunc

    [/autoit]
  • Und das hier:

    [autoit]


    #include <GDIPlus.au3>
    _GDIPlus_Startup()

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

    $Pic = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\auge.jpg") ;entsprechend abändern!
    $width = _GDIPlus_ImageGetWidth($Pic) * 2
    $height = _GDIPlus_ImageGetHeight($Pic) * 2
    $hGui = GUICreate("Test", $width, $height, -1, -1)
    $hGDI = _GDIPlus_GraphicsCreateFromHWND($hGui)

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

    GUISetState()
    _GDIPlus_GraphicsDrawImageRect($hGDI, $Pic, 0, 0, $width, $height)

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

    Do
    Until Not Sleep(50) + GUIGetMsg() = -3

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

    _GDIPlus_GraphicsDispose ($hGDI)
    _GDIPlus_ShutDown ()

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

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (4. November 2009 um 10:44)

  • UEZ: da entsteht genau das gleiche Problem

    habs auch schon mit _GDIPlus_GraphicsDrawImageRectRect _GDIPlus_DrawImagePoints probiert,
    klappt aber nicht ;(

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    _GDIPlus_Startup()

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

    $Pic = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\FrameTop.png") ;entsprechend abändern!
    $width = _GDIPlus_ImageGetWidth($Pic) * 150
    $height = _GDIPlus_ImageGetHeight($Pic) * 1
    $hGui = GUICreate("Test", $width, $height, -1, -1)
    $hGDI = _GDIPlus_GraphicsCreateFromHWND($hGui)

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

    GUISetState()
    _GDIPlus_GraphicsDrawImageRect($hGDI, $Pic, 0, 0, $width, $height)

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

    Do
    Until Not Sleep(50) + GUIGetMsg() = -3

    [/autoit]


    mit dem Bild aus Post 4 kommt folgender Farbverlauf herraus:
    autoit.de/wcf/attachment/6575/

  • Hier, was mir als 1. eingefallen ist (Bruteforce):

    [autoit]


    #include <GDIPlus.au3>
    _GDIPlus_Startup()
    $Pic = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\FrameTop.png")

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

    $width = 150
    $height = 100
    $ix = _GDIPlus_ImageGetWidth($Pic)
    $iy = _GDIPlus_ImageGetHeight($Pic)
    $hGui = GUICreate("Test", $width, $height, -1, -1)

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

    $hGDI = _GDIPlus_GraphicsCreateFromHWND($hGui)

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

    $dx = Int($width / $ix) + 1
    $dy = Int($height / $iy) + 1

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

    GUISetState()

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

    For $x = 0 To $dx Step $ix
    _GDIPlus_GraphicsDrawImageRect($hGDI, $Pic, $x, 0, $ix, $height) ;copy to bitmap
    Next

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

    Do
    Until Not Sleep(50) + GUIGetMsg() = -3

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

    _GDIPlus_GraphicsDispose ($hGDI)
    _GDIPlus_ShutDown ()

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hier eine andere Methode, die ich im engl. Forum gefunden habe!

    Allerdings muss vorher dein PNG in BMP umgewandelt werden:

    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>

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

    Const $Style_Stretch = 1, $Style_Tile = 2, $Style_Center = 3
    Global $hBitmap, $ImageHeight, $ImageWidth, $Image_Style, $width, $height
    $width = 150
    $height = 100
    $Form = GUICreate("Form", $width, $height)
    LoadBitmap_FromFile("FrameTop.bmp", $Style_Stretch)
    GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")
    GUISetState(@SW_SHOW)

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

    Do
    Until Not Sleep(50) + GUIGetMsg() = -3

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

    Func WM_ERASEBKGND($hWnd, $Msg, $wParam, $lParam)
    If $hBitmap Then
    $D_C = _WinAPI_CreateCompatibleDC($wParam)
    $Object = _WinAPI_SelectObject($D_C, $hBitmap)

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

    Select
    Case $Image_Style = 1
    StretchBlt($wParam, 0, 0, _WinAPI_GetClientWidth($hWnd), _WinAPI_GetClientHeight($hWnd), $D_C, 0, 0, _
    $ImageWidth, $ImageHeight, $SRCCOPY)

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

    Case $Image_Style = 2
    For $i1 = 0 To (_WinAPI_GetClientHeight($hWnd) - 1) Step $ImageHeight
    For $i2 = 0 To (_WinAPI_GetClientWidth($hWnd) - 1) Step $ImageWidth
    _WinAPI_BitBlt($wParam, $i2, $i1, _WinAPI_GetClientWidth($hWnd), _WinAPI_GetClientHeight($hWnd), _
    $D_C, 0, 0, $SRCCOPY)
    Next
    Next

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

    Case $Image_Style = 3
    If ($ImageWidth < _WinAPI_GetClientWidth($hWnd)) Then
    $i2 = ((_WinAPI_GetClientWidth($hWnd) - $ImageWidth) / 2)
    Else
    $i2 = 0
    EndIf
    If ($ImageHeight < _WinAPI_GetClientHeight($hWnd)) Then
    $i1 = ((_WinAPI_GetClientHeight($hWnd) - $ImageHeight) / 2)
    Else
    $i1 = 0
    EndIf
    _WinAPI_BitBlt($wParam, $i2, $i1, _WinAPI_GetClientWidth($hWnd), _WinAPI_GetClientHeight($hWnd), _
    $D_C, 0, 0, $SRCCOPY)
    EndSelect

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

    $Object = _WinAPI_SelectObject($D_C, $Object)

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

    Return True
    EndIf
    EndFunc ;==>WM_ERASEBKGND

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

    Func StretchBlt($hdcDest, $nXOriginDest, $nYOriginDest, $nWidthDest, $nHeightDest, $hdcSrc, $nXOriginSrc, _
    $nYOriginSrc, $nWidthSrc, $nHeightSrc, $dwRop)
    $DllCall = DllCall("Gdi32.dll", "int", "StretchBlt", "hwnd", $hdcDest, "int", $nXOriginDest, "int", $nYOriginDest, "int", $nWidthDest, _
    "int", $nHeightDest, "hwnd", $hdcSrc, "int", $nXOriginSrc, "int", $nYOriginSrc, "int", $nWidthSrc, "int", $nHeightSrc, "long", $dwRop)
    Return $DllCall[0]
    EndFunc ;==>StretchBlt

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

    Func LoadBitmap_FromFile($sFileName, $ImageStyle)
    $IMAGE_BITMAP = 0
    $LR_LOADFROMFILE = 0x0010
    $hBitmap = _WinAPI_LoadImage(_WinAPI_GetModuleHandle(0), $sFileName, $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE)
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $ImageWidth = _GDIPlus_ImageGetWidth($hImage)
    $ImageHeight = _GDIPlus_ImageGetHeight($hImage)
    $Image_Style = $ImageStyle
    _GDIPlus_Shutdown()
    EndFunc ;==>LoadBitmap_FromFile

    [/autoit]


    Vielleicht auch mal nützlich!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯