The GDI Plus library has some very clever stuff in it - which is enough to scare most people off. Only the brave and talented have mastered it - the rest of us just creep around the edges. Fortunately, only a few API calls are needed to load and display many image formats, and the results are - at least for those of us who are dealing with photographic images - very acceptable, and superior for this purpose to the "builtin" functions like GRAPHIC STRETCH.

I started with Patrice Terrier's include file and whittled it doen to a bare minimum to load and resize an image. The include file is below, with a little demonstration program. You will need an image file called test.jpg in the same directory as the application. Or you can change the code, of course. I suggest that you use a photographic image.

*** Added *** also, note that the aspect ratio is preserved. (This is not a GDIP exclusive!)



include file picogdip.inc:
Code:
'--------------------------------------------------------------------------------
' picoGDIP.inc  placed in public domain by Chris Holbrook May 2008
'
' based on code by Messrs Terrier, Schullian, Walker & others, thanks to Simon Morgan for debugging.
' modified Jan 2008: globals no longer used
'          Dec 2008: some redundant code removed
'--------------------------------------------------------------------------------
'GDIP CONSTANTS
%QualityModeHigh = 2       ' Best rendering quality
%UnitPixel       = 2 ' Each unit is one device pixel.
'--------------------------------------------------------------------------------
' pico-GDIP.inc
'
'-----------------------------------------------------------------------------------------------------------------------
'
type GdiplusStartupInput
   GdiplusVersion as dword             '// Must be 1
   DebugEventCallback as dword         '// Ignored on free builds
   SuppressBackgroundThread as long    '// FALSE unless you're prepared to call
                                       '// the hook/unhook functions properly
   SuppressExternalCodecs as long      '// FALSE unless you want GDI+ only to use
                                       '// its internal image codecs.
end type

'
'-----------------------------------------------------------------------------------------------------------------------
'
type GdiplusStartupOutput
'  // The following 2 fields are NULL if SuppressBackgroundThread is FALSE.
'  // Otherwise, they are functions which must be called appropriately to
'  // replace the background thread.
'  //
'  // These should be called on the application's main message loop - i.e.
'  // a message loop which is active for the lifetime of GDI+.
'  // "NotificationHook" should be called before starting the loop,
'  // and "NotificationUnhook" should be called after the loop ends.
   NotificationHook as dword
   NotificationUnhook as dword
end type
'
'-----------------------------------------------------------------------------------------------------------------------

type ImageCodecInfo
   ClassID as guid            '// CLSID. Codec identifier
   FormatID as guid           '// GUID. File format identifier
   CodecName as dword         '// WCHAR*. Pointer to a null-terminated string
                              '// that contains the codec name
   DllName as dword           '// WCHAR*. Pointer to a null-terminated string
                              '// that contains the path name of the DLL in
                              '// which the codec resides. If the codec is not
                              '// a DLL, this pointer is NULL
   FormatDescription as dword '// WCHAR*. Pointer to a null-terminated string
                              '// that contains the name of the format used by the codec
   FilenameExtension as dword '// WCHAR*. Pointer to a null-terminated string
                              '// that contains all file-name extensions associated
                              '// with the codec. The extensions are separated with semicolons.
   MimeType as dword          '// WCHAR*. Pointer to a null-terminated string
                              '// that contains the mime type of the codec
   Flags as dword             '// Combination of flags from the ImageCodecFlags enumeration
   Version as dword           '// Integer that indicates the version of the codec
   SigCount as dword          '// Integer that indicates the number of signatures
                              '// used by the file format associated with the codec
   SigSize as dword           '// Integer that indicates the number of bytes of each signature
   SigPattern as dword        '// BYTE*. Pointer to an array of bytes that contains
                              '// the pattern for each signature
   SigMask as dword           '// BYTE*. Pointer to an array of bytes that contains
                              '// the mask for each signature
end type
'-----------------------------------------------------------------------------------------------------------------------
'
declare function GdipSetInterpolationMode lib "gdiplus.dll" alias "GdipSetInterpolationMode" (byval graphics as long, byval interpolation as long) as long
declare function GdipDrawImageRectI lib "gdiplus.dll" alias "GdipDrawImageRectI" (byval graphics as long, byval nImage as long, byval x as long, byval y as long, byval nWidth as long, byval Height as long) as long

declare function GdipGetImageWidth lib "gdiplus.dll" alias "GdipGetImageWidth" (byval nImage as long, nWidth as long) as long
declare function GdipGetImageHeight lib "gdiplus.dll" alias "GdipGetImageHeight" (byval nImage as long, Height as long) as long

declare function GdipDeleteGraphics lib "gdiplus.dll" alias "GdipDeleteGraphics" (byval graphics as long) as long

declare function GdipGraphicsClear lib "gdiplus.dll" alias "GdipGraphicsClear" (byval graphics as long, byval lColor as long) as long
declare function GdipCreateFromHWND lib "gdiplus.dll" alias "GdipCreateFromHWND" (byval hwnd as long, graphics as long) as long
declare function GdipCreateFromHDC lib "gdiplus.dll" alias "GdipCreateFromHDC" (byval hdc as long, graphics as long) as long

declare function GdipGetImagePixelFormat lib "gdiplus.dll" alias "GdipGetImagePixelFormat" _
            (byval nImage as long, PixelFormat as long) as long
declare function GdipGetImageDimension lib "gdiplus.dll" alias "GdipGetImageDimension" _
            (byval nImage as long, nWidth as single, Height as single) as long
declare function GdipGetImageGraphicsContext lib "gdiplus.dll" alias "GdipGetImageGraphicsContext" _
            (byval nImage as long, graphics as long) as long
declare function GdiplusStartup lib "GDIPLUS.DLL" alias "GdiplusStartup" _
            (token as dword, inputbuf as GdiplusStartupInput, outputbuf as GdiplusStartupOutput) as long
declare sub GdiplusShutdown lib "GDIPLUS.DLL" alias "GdiplusShutdown" _
            (byval token as dword)
declare function GdipLoadImageFromFile lib "GDIPLUS.DLL" alias "GdipLoadImageFromFile" _
            (byval flname as string, lpImage as dword) as long
declare function GdipDisposeImage lib "GDIPLUS.DLL" alias "GdipDisposeImage" _
            (byval lpImage as dword) as long
declare function GdipCreateBitmapFromScan0 lib "gdiplus.dll" alias "GdipCreateBitmapFromScan0" _
            (byval nWidth as long, byval Height as long, byval stride as long, byval PixelFormat as long, _
             scan0 as any, nBitmap as long) as long
declare function GdipGetInterpolationMode lib "gdiplus.dll" alias "GdipGetInterpolationMode" _
            (byval graphics as long, interpolation as long) as long
declare function GdipDrawImageRectRectI lib "gdiplus.dll" alias "GdipDrawImageRectRectI" _
            (byval graphics as long, byval nImage as long, byval dstx as long, byval dsty as long, _
             byval dstwidth as long,  byval dstheight as long, byval srcx as long, byval srcy as long, _
             byval srcwidth as long, byval srcheight as long, byval srcUnit as long, _
             optional byval imageAttributes as long, optional byval pCALLBACK as long, _
             optional byval callbackData as long) as long
declare sub skIconise (byval xPic as long, byval yPic as long,            _ picture dimensions
               byval xCell as long, byval yCell as long,          _ FRAME dimensions
               byref xOfs as long, byref yOfs as long,            _ calc'd offset in frame
               byref xSize as long, byref ySize as long)   ' thumbnail dimensions
'

'-----------------------------------------------------------------------------------------------------------------------
' write resized image to file and/or window.
function ResizeImage (picpath as string, hW as dword, maxwidth as dword, maxheight as dword) as long
    local origwidth as single
    local origheight as single
    local lPixelFormat as long
    local s as string
    local extn as string
    local imagestyle as string
    local lresult, OfsX, OfsY, Tx, Ty as long
    local hbitmap, himage, graphics as dword
    local encoderCLSID as GUIDAPI

    GDIPLoadImageFromFile ucode$(picPath), hImage
    '
    if hImage = 0 then
        ' return image handle value of zero to indicate failure
        exit function
    end if
    '
    GdipGetImageDimension hImage, origwidth, origheight
    '
    skIconise ( origwidth, origheight, maxwidth, maxheight, ofsX, ofsY, tX, tY)
    '
    GdipGetImagePixelFormat hImage, lPixelFormat

    ' create right-size bitmap
    GdipCreateBitmapFromScan0 tX, tY, 0, lPixelFormat, byval 0&, hBitmap
    ' get graphics handle to bitmap
    GdipGetImageGraphicsContext hBitmap, graphics
    GdipSetInterpolationMode graphics, %QualityModeHigh
    ' drop image into graphics object
    GdipDrawImageRectRectI graphics, hImage, 0, 0, tX, tY, 0, 0, origwidth, origheight, %UnitPixel
    ' get rid of GDI objects
    call GdipDeleteGraphics(graphics)
    deleteobject hbitmap
    function = himage
end function
'
'-------------------------------------------------------------------------------------------------------
' Computes location and size to stretch a bitmap preserving its aspect.
'
sub skIconise (byval xPic as long, byval yPic as long,            _ picture dimensions
               byval xCell as long, byval yCell as long,          _ FRAME dimensions
               byref xOfs as long, byref yOfs as long,            _ calc'd offset in frame
               byref xSize as long, byref ySize as long) export   ' thumbnail dimensions
  local scale as single

    if xPIC& then scale! = xCell& / xPic&
    if scale! > 1 then scale! = 1
    xSize& = xPic& * scale!: ySize& = yPic& * scale!
  ' In case Height > 150 compute new scale factor
    if ySize& > yCell& then
       if yPic& then scale! = yCell& / yPic&
       xSize& = xPic& * scale!: ySize& = yPic& * scale!
    end if
    xOfs& = (xCell& - xSize&) \ 2
    yOfs& = (yCell& - ySize&) \ 2
end sub
demo program:
Code:
' to show GDIPlus resizing an image in a GRAPHIC WINDOW
' Chris Holbrook 7 Dec 2008

#compile exe
#dim all
#include once "win32api.inc"
#include once "picogdip.inc"

%pic_margin = 3
    '----------------------------------------------------------------------
sub ShowImage ( hwin as dword, currentrect as rect, gdip_image as dword)
    local hdc, hG as dword
    local tx, ty, framex, framey, ofsx, ofsy as long
    local wide, high as single

    graphic get dc to hDC
    frameX = currentrect.nRight - currentrect.nLeft
    frameY = currentrect.nBottom - currentrect.nTop
    GdipGetImageDimension gdip_Image, wide, high
    ' calc coordinates to centre image in frame, retaining original proportion
    skIconise ( wide, high, frameX, frameY, ofsX, ofsY, tX, tY)
    if GdipCreatefromHDC ( hDC, hG) =  0 then
        if hG <> 0 then
           ' can also set smoothing mode, etc here
           GdipSetInterpolationMode(hG, %QualityModeHigh)
           GdipDrawImageRectI(hG, gdip_image, currentrect.nleft + %pic_margin, _
                                              currentrect.ntop + %pic_margin, _
                                              tX - 2*%pic_margin, tY - 2 * %pic_margin )
           if hG <> 0 then gdipdeletegraphics hG
        end if
    end if
    graphic redraw
end sub

function pbmain () as long
    static nstatus as long
    static token as dword
    static StartupInput as GdiplusStartupInput
    local skey as string
    local currentrect as rect
    local gdip_image as dword
    local clicked, X, Y as long
    local pt as point
    
    StartupInput.GdiplusVersion = 1
    nStatus = GdiplusStartup(token, StartupInput, byval %NULL)
    if nStatus then
        ?  "Error initializing GDI+", %mb_applmodal, "Warning"
        exit function
    end if

    ' Create and show a Graphic window on screen

    local hWin as dword

    graphic window "", 130, 130, 500, 500 to hWin

    graphic attach hWin, 0, redraw
    graphic set pos (0,0)
    
    setrect currentrect, 0, 30, 250, 250
    gdip_image = resizeimage ( "test.jpg", hwin, _
                           currentrect.nright - currentrect.nleft, _
                           currentrect.nbottom - currentrect.ntop )
    do
        graphic clear -1, 0
        graphic print "GDIP is being used to resize the image on a GRAPHIC WINDOW"
        graphic print "Use the mouse to size the image. Press esc to exit"
        showimage ( hWin, currentrect , gdip_image)
        sleep 2
        getcursorpos pt  ' a crude way of tracking the mouse!
        
        if (currentrect.nright <> pt.X ) or (currentrect.nbottom <> pt.Y ) then
            currentrect.nright = pt.X
            currentrect.nbottom = pt.Y
        else
            skey = ""
            graphic inkey$ to skey
            if skey = $esc then exit loop
        end if
    loop
                                                          
    GdiplusShutdown token
    graphic window end

end function