GDI+ Bitmap skalieren

  • Hey @ all,

    ich habe mit _GDIPlus_ImageLoadFromFile ein Bild reingeladen. Nun möchte ich dieses zuerst skalieren (width und height verzerren) und dann mit _GDIPlus_GraphicsDrawImageRectRect weiterverarbeiten. Nur wie kann man ein Image skalieren ohne es dabei direkt auf den Bildschirm zu bringen?

    mfG
    Developer30

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

    Einmal editiert, zuletzt von Developer30 (7. Februar 2011 um 21:05)

  • Hi,

    im Speicher. Du musst einen (zu deiner Bitmap) kompatiblen Gerätekontext im Speicher erzeugen via _WinAPI_CreateCompatibleDC oder _GDIPlus_GraphicsCreateFromHDC/HWND

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <ScreenCapture.au3>

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

    Opt('MustDeclareVars', 1)

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

    Global Const $HWND_DESKTOP = 0

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

    _Main()

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

    Func _Main()
    Local $hdc, $hdcMem, $hImage, $hGraphic

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

    ; Capture top left corner of the screen
    _ScreenCapture_Capture (@MyDocumentsDir & "\GDIPlus_Image.jpg", 0, 0, 400, 300)

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

    ; Initialize GDI+ library and load image
    _GDIPlus_Startup ()
    $hImage = _GDIPlus_ImageLoadFromFile (@MyDocumentsDir & "\GDIPlus_Image.jpg")

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

    $hdc = _WinAPI_GetDC ($HWND_DESKTOP)
    $hdcMem = _WinAPI_CreateCompatibleDC ($hdc)
    _WinAPI_ReleaseDC ($HWND_DESKTOP, $hdc)

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

    $hGraphic = _GDIPlus_GraphicsCreateFromHDC ($hdcMem)

    ; Draw 2x zoomed image
    _GDIPlus_GraphicsDrawImageRectRect ($hGraphic, $hImage, 0, 0, 200, 200, 0, 0, 400, 300)

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

    ; Release resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hImage)
    _WinAPI_DeleteDC ($hdcMem) ; Gerätekontext wieder freigeben
    _GDIPlus_Shutdown ()

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

    ; Clean up screen shot file
    FileDelete(@MyDocumentsDir & "\GDIPlus_Image.jpg")

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

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

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

    EndFunc ;==>_Main

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


    Gruß
    Greenhorn


    4 Mal editiert, zuletzt von Greenhorn (7. Februar 2011 um 20:10)

  • Probiere es mal damit:

    Spoiler anzeigen
    [autoit]


    ;coded by UEZ 2011
    #include <GDIPlus.au3>

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

    $file = FileOpenDialog("Select an image", "", "Images (*.jpg;*.png;*bmp;*gif,*.tif)")
    If @error Then Exit
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($file)
    $newBitmap = Scale_Image($hImage, 320, 256)
    _GDIPlus_ImageSaveToFile($newBitmap, @ScriptDir & "\Test.jpg")
    ShellExecute(@ScriptDir & "\Test.jpg")

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

    Func Scale_Image($hImage, $newW, $newH)
    Local $newImage = _GDIPlus_BitmapCreateFromScan0($newW, $newH)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($newImage)
    _GDIPlus_GraphicsSetInterpolationMode($hContext, 7)
    _GDIPlus_GraphicsDrawImageRect($hContext, $hImage, 0, 0, $newW, $newH)
    _GDIPlus_GraphicsDispose($hContext)
    Return SetError(0, 0, $newImage)
    EndFunc

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

    Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[6]
    EndFunc ;==>_GDIPlus_BitmapCreateFromScan0

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

    Func _GDIPlus_GraphicsSetInterpolationMode($hGraphics, $iInterpolationMode)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGraphics, "int", $iInterpolationMode)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_GraphicsSetInterpolationMode

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • :D ich glaube ich versteh das jetzt. thx @ all, ihr habt mir weitergeholfen :thumbup:

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."