Announcement

Collapse
No announcement yet.

GDI+ ... how to load a non-BMP image ie PNG/JPG and convert it to a BMP?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Wayne Diamond
    replied
    Cool, Jose I downloaded that demo of yours and the BMP was read successfully (was a big relief to call that API successfully after so many failed attempts!), then I changed it over to a PNG but it failed with error 2 again. But changing the pixel format to %PixelFormat24bppRGB fixed that (which works for both 8 and 24bit PNGs - strangely %PixelFormat8bppIndexed didnt work for the 8bit one). %PixelFormat24bppRGB seems to be the only one that works for PNG

    Ok so now that ive finally got access to this damned bitmap data I can start the real work

    Many cheers again Jose and Patrice

    ps. awesome GDI header file Jose, looks very complete

    Leave a comment:


  • Patrice Terrier
    replied
    Ok, for those wanting to take it the hard way ( easy way is GDImage )

    One important thing you must be aware: GDIPLUS graphics are full 32-bit and the alpha channel must be preserved if you want to work with graphic formats using it, like PNG files for example.

    Code:
    ' Information about image pixel data
    TYPE BitmapData
       nWIDTH AS LONG
       nHeight AS LONG
       stride AS LONG
       PixelFormat AS LONG
       scan0 AS LONG
       Reserved AS LONG
    END TYPE
    
    %ImageLockModeRead = &H1
    %ImageLockModeWrite = &H2
    %ImageLockModeUserInputBuf = &H4
    
    DECLARE FUNCTION GdipBitmapLockBits LIB "gdiplus.dll" ALIAS "GdipBitmapLockBits" (BYVAL nBitmap AS LONG, nRect AS RECTL, BYVAL ImageLockMode AS LONG, BYVAL PixelFormat AS LONG, lockedBitmapData AS BitmapData) AS LONG
    DECLARE FUNCTION GdipBitmapUnlockBits LIB "gdiplus.dll" ALIAS "GdipBitmapUnlockBits" (BYVAL nBitmap AS LONG, lockedBitmapData AS BitmapData) AS LONG
    Code:
    TYPE MYBITMAPINFO
        bmiHeader AS BITMAPINFOHEADER
        bmiColors(256) AS RGBQUAD ' Patrice
    END TYPE
    
    FUNCTION zGetDIBits ALIAS "zGetDIBits" (BYVAL hBitmap AS LONG, PixelArray() AS LONG) EXPORT AS LONG
        LOCAL bi AS MYBITMAPINFO
        LOCAL bm AS BITMAP
        LOCAL dwp AS DWORD PTR
        LOCAL hIC AS LONG, hDC AS LONG
        IF hBitmap THEN
           hIC = zDisplayDC()
           hDC = CreateCompatibleDC(hIC)
           CALL SelectObject(hDC, hBitmap)
    
           CALL GetObject(hBitmap, SIZEOF(bm), bm)
           bi.bmiHeader.biSize        = SIZEOF(bi.bmiHeader)
           bi.bmiHeader.biWidth       = bm.bmWidth
           bi.bmiHeader.biHeight      = -bm.bmHeight ' Put top in TOP instead on bottom!
           bi.bmiHeader.biPlanes      = 1
           bi.bmiHeader.biBitCount    = 32
           bi.bmiHeader.biCompression = %BI_RGB
           REDIM PixelArray(bm.bmWidth - 1, bm.bmHeight - 1) AS LONG
           dwp = VARPTR(PixelArray(0,0))
           FUNCTION = GetDIBits(hDC, hBitmap, 0, bm.bmHeight, BYVAL dwp, bi, %DIB_RGB_COLORS)
    
           CALL DeleteDC(hIC)
           CALL DeleteDC(hDC)
    
        END IF
    END FUNCTION
    '
    FUNCTION zSetDIBits ALIAS "zSetDIBits" (BYVAL hBitmap AS LONG, PixelArray() AS LONG) EXPORT AS LONG
        LOCAL bi AS MYBITMAPINFO
        LOCAL bm AS BITMAP
        LOCAL dwp AS DWORD PTR
        LOCAL hIC AS LONG, hDC AS LONG
        IF hBitmap THEN
           hIC = zDisplayDC()
           hDC = CreateCompatibleDC(hIC)
           CALL SelectObject(hDC, hBitmap)
    
           CALL GetObject(hBitmap, SIZEOF(bm), bm)
           bi.bmiHeader.biSize        = SIZEOF(bi.bmiHeader)
           bi.bmiHeader.biWidth       = bm.bmWidth
           bi.bmiHeader.biHeight      = -bm.bmHeight ' Put top in TOP instead on bottom!
           bi.bmiHeader.biPlanes      = 1
           bi.bmiHeader.biBitCount    = 32
           bi.bmiHeader.biCompression = %BI_RGB
           dwp = VARPTR(PixelArray(0,0))
           FUNCTION = SetDIBits(hDC, hBitmap, 0, bm.bmHeight, BYVAL dwp, bi, %DIB_RGB_COLORS)
    
           CALL DeleteDC(hIC)
           CALL DeleteDC(hDC)
    
        END IF
    END FUNCTION
    In the GDImage trial version, look at the source code of resource.bas and search for ZD_GetBitmapObjectBits and ZD_SetBitmapObjectBits they are the helper functions to manipulate a pixel array.

    ...
    Last edited by Patrice Terrier; 4 May 2008, 06:36 AM.

    Leave a comment:


  • José Roca
    replied
    I have already posted the link for TB_GDIPLUS.INC
    http://www.jose.it-berater.org/smffo...php?topic=88.0

    It is included included in the file TB_GDIPLUS.ZIP, posted as an attachment, but you won't see it nor download it unless you register first as a member of the forum.

    Code:
    TYPE BitmapData
       nWidth AS DWORD
       nHeight AS DWORD
       Stride AS LONG
       PixelFormat AS DWORD
       Scan0 AS DWORD
       Reserved AS DWORD
    END TYPE
    Code:
    DECLARE FUNCTION GdipBitmapLockBits LIB "GDIPLUS.DLL" ALIAS "GdipBitmapLockBits" ( _
        BYVAL pbitmap AS DWORD _                            ' *GpBitmap
      , BYREF prect AS RECTL _                              ' *GDIPCONST GpRect <record>
      , BYVAL flags AS DWORD _                              ' UINT
      , BYVAL PixelFormat AS LONG _                         ' PixelFormat
      , BYREF lockedBitmapData AS BitmapData _              ' *BitmapData <record>
        ) AS LONG                                           ' GpStatus <enum>
    I have run the example and works fine with the bitmap file included in the attachment.

    Leave a comment:


  • Wayne Diamond
    replied
    Originally posted by José Roca View Post
    There are some 150 GDI+ examples in my forum. This one shows how to lock pixels for reading and access the Scan0 member:
    http://www.jose.it-berater.org/smffo...picseen#msg421
    Hmmm even that one is failing on GdipBitmapLockBits with an error code of 2, just like my one is. I tried it with a BMP file instead of a PNG but still the same fail, any ideas? Apparently error #2 = Invalid Parameter. A google for GdipBitmapLockBits shows that it seems to be a common problem

    One guy said "i found data type BitmapData has multiple defines, one in bitmap-private.h and another in GdiPlusFlat.h, this cause the error", but he didn't have a fix for it

    So maybe my defines are wrong ... I couldn't find TB_GDIPLUS.INC so I had to use my own definitions, could you hit me with a link to that include file please? I used the Search function at your forum but it didnt find any matches. Hopefully that'll fix the problem!

    Many thanks again

    Leave a comment:


  • Patrice Terrier
    replied
    Wayne

    GDImage is the only graphic package that would work with VISTA in DWM composited mode.

    If you have at least VISTA Premium try this:
    The GDImage Crystal demo on José Roca's forum

    ...

    Leave a comment:


  • Wayne Diamond
    replied
    Originally posted by Patrice Terrier View Post
    Wayne,
    If the function succeeds, the return value is the number of scan lines copied.
    Yep that sounds exactly like the same sort of thing I'm trying to do here, very cool!
    I'll try to accomplish this with raw GDI+ first but if I get nowhere with that then I'll definately give GDImage a burl

    ps. can I just say it's bloody awesome what yourself and Jose have managed to do in regards to making GDI+ available to PB programmers. (I mean now we can use PNG/GIF/TIFF/JPG which we couldnt before!)
    I mean if Poffs stats are anything to go by then not too many people have done too much work in GDI+, but you two have contributed a hell of a lot and I've no doubt that a LOT of PB programmers would've benefited greatly from your contributions.
    I think a lot of people here including myself owe you both a round of drinks lol
    Awesome work guys, absolutely awesome. I hereby declare Patrice and Jose GDI+ Jedis !

    Leave a comment:


  • Patrice Terrier
    replied
    Wayne,

    If it is for your private use then you could use the GDImage trial version, it has built-in function to retrieve the pixels form any image under the form of an array.

    Low level procedure to retrieve a device-independent bitmap.

    FUNCTION zGetDIBits ( _
    BYVAL hBitmap AS LONG, _ ' A valid bitmap handle.
    PixelArray() AS LONG _ ' Array using 2 dimensions (Y,Y) matching the pixel coordinates.
    ) AS LONG


    Return:
    If the function succeeds, the return value is the number of scan lines copied.
    If the function fails, the return value is zero.

    Low level procedure to replace a copy of a bitmap that was retrieved as a device-independent bitmap.

    FUNCTION zSetDIBits ( _
    BYVAL hBitmap AS LONG, _ ' A valid bitmap handle.
    PixelArray() AS LONG _ ' Array using 2 dimensions (Y,Y) matching the pixel coordinates.
    ) AS LONG


    Return:
    If the function succeeds, the return value is the number of scan lines copied from the bitmap.

    ...

    Leave a comment:


  • Wayne Diamond
    replied
    Originally posted by José Roca View Post
    This one shows how to lock pixels for reading and access the Scan0 member:
    http://www.jose.it-berater.org/smffo...picseen#msg421
    One word - WOOOHOOO!!! (or is that 2?)
    That example looks like exactly the thing I was after, awesome

    Scan0 here I come

    Leave a comment:


  • José Roca
    replied
    There are some 150 GDI+ examples in my forum. This one shows how to lock pixels for reading and access the Scan0 member:
    http://www.jose.it-berater.org/smffo...picseen#msg421

    Each example has an attachment (only visible and downloadable if you are a registered user) containing a full, compilable example.

    Also, don't forget to release the bitmap using GdipDisposeImage pBitmap when done.

    Complete headers for GDI+ can be downloaded here: http://www.jose.it-berater.org/smffo...php?topic=88.0

    BTW there are also headers for FreeImage: http://www.jose.it-berater.org/smffo...p?topic=1488.0
    and many other graphic libraries. Even wrapper functions and examples for DirectX9.

    Leave a comment:


  • Wayne Diamond
    replied
    Bugger! It seems that's only half the job done ... the data at pBitmap isn't actually the pixel data. There's an address there, but if I go to that there's more data, but again not the pixel data in bitmap form.

    But I think I'm only 1 more GDI+ API away from the pixel data...

    From a bit more reading it seems I may need to call GdipBitmapLockBits, but according to POFFS nobody has ever used it before! Apparently that API is supposed to give you access to this structure:
    TYPE BitmapData
    nWIDTH AS LONG
    nHeight AS LONG
    stride AS LONG
    PixelFormat AS LONG
    scan0 AS LONG '<--- PTR to the actual pixel data I'm after!
    Reserved AS LONG
    END TYPE

    But I'm not getting very far with it and its starting to do my head in!
    Here's what I've come up with so far, any ideas???

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "win32api.inc"
    
    %SHIFT_LEFT_8_8  = 2048
    %SHIFT_LEFT_32_8 = 8192
    %PixelFormatIndexed     = &h00010000 ' Indexes into a palette
    %PixelFormatGDI         = &h00020000 ' Is a GDI-supported format
    %PixelFormatAlpha       = &h00040000 ' Has an alpha component
    %PixelFormatPAlpha      = &h00080000 ' Pre-multiplied alpha
    %PixelFormatExtended    = &h00100000 ' Extended color 16 bits/channel
    %PixelFormatCanonical   = &h00200000
    %PixelFormatUndefined   = 0
    %PixelFormatDontCare    = 0
    %PixelFormat8bppIndexed     =  3 OR %SHIFT_LEFT_8_8  OR %PixelFormatIndexed OR %PixelFormatGDI
    %PixelFormat32bppRGB        =  9 OR %SHIFT_LEFT_32_8 OR %PixelFormatGDI
    %PixelFormat32bppARGB       = 10 OR %SHIFT_LEFT_32_8 OR %PixelFormatAlpha OR %PixelFormatGDI OR %PixelFormatCanonical
    %PixelFormat32bppPARGB      = 11 OR %SHIFT_LEFT_32_8 OR %PixelFormatAlpha OR %PixelFormatPAlpha OR %PixelFormatGDI
    
    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
       NotificationHook AS DWORD
       NotificationUnhook AS DWORD
    END TYPE
    
    DECLARE FUNCTION GdipCreateBitmapFromFile LIB "GDIPLUS.DLL" ALIAS "GdipCreateBitmapFromFile" ( _
       BYVAL STRING _                           ' GDIPCONST WCHAR *filename
     , BYREF DWORD _                            ' GpBitmap **bitmap
     ) AS LONG                                  ' GpStatus
    
    DECLARE FUNCTION GdipCreateHBITMAPFromBitmap LIB "GDIPLUS.DLL" ALIAS "GdipCreateHBITMAPFromBitmap" ( _
       BYVAL DWORD _                            ' GpBitmap *bitmap
     , BYREF DWORD _                            ' HBITMAP *hbmReturn
     , BYVAL DWORD _                            ' ARGB background
     ) AS LONG                                  ' GpStatus
    
    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)
    
    TYPE BitmapData
       nWIDTH AS LONG
       nHeight AS LONG
       stride AS LONG
       PixelFormat AS LONG
       scan0 AS LONG
       Reserved AS LONG
    END TYPE
    
    DECLARE FUNCTION GdipBitmapLockBits LIB "gdiplus.dll" ALIAS "GdipBitmapLockBits" (BYVAL nBitmap AS LONG, nRect AS RECTL, BYVAL flags AS LONG, BYVAL PixelFormat AS LONG, lockedBitmapData AS BitmapData) AS LONG
    
    FUNCTION PBMAIN () AS LONG
    LOCAL hr AS LONG, strFileName AS STRING, pBitmap AS DWORD, hBitmap AS DWORD, token AS DWORD, nStatus AS LONG
    LOCAL StartupInput AS GdiplusStartupInput, nRect AS RECTL, bmpData AS BitmapData
    
    StartupInput.GdiplusVersion = 1
    nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
    IF nStatus THEN
       MSGBOX "Error initializing GDI+": EXIT FUNCTION
    END IF
    
    strFilename = UCODE$("E:\temp\test.png")
    hr = GdipCreateBitmapFromFile (strFileName, pBitmap)
    'hr = GdipCreateHBITMAPFromBitmap (pBitmap, hBitmap, 0)   '// Probably not required?
    
    MSGBOX "Lock=" & STR$(GdipBitmapLockBits (BYVAL dwPtr, nRect, BYVAL 1, BYVAL 0, bmpData))
    MSGBOX "Width=" & STR$(bmpData.nWIDTH) & ", Height=" & STR$(bmpData.nHeight)
    
    GdiplusShutdown token
    END FUNCTION

    Leave a comment:


  • Wayne Diamond
    replied
    Too easy! I had a feeling that there might be such an elegantly simple solution in GDI+ but this is the first time I've got my feet wet with it, and as it exports so many APIs I didn't know where to start. I searched through all the GDI+ samples I could find but couldn't really find one that just did this.

    btw I thought there was some problem with your code at first because I was getting 0 for hBitmap and pBitmap ...... half an hour later I realised none of it will work unless I call GdiplusStartup first ... this fixed the problem

    Thankyou very much Jose, I can begin tackling the real problem now - the in-memory image analysis itself. This should be fun!

    Thanks also Tyrone for pointing me towards that free image library, it looks pretty interesting so I'll have to check it out

    Thanks again and have a great weekend!

    Leave a comment:


  • Wayne Diamond
    replied
    Very cool! I will have a thorough look through it tomorrow
    No surprise to see that Patrice has his own board for graphics lol

    Leave a comment:


  • José Roca
    replied
    When you find the time, take a tour in my forum: http://www.jose.it-berater.org/smfforum/index.php

    There is a board devoted to graphics programming, with tons of examples, and Patrice has his own board.
    Last edited by José Roca; 2 May 2008, 10:04 AM.

    Leave a comment:


  • Wayne Diamond
    replied
    Jose it is very late in the night here so I can't try that out now but I will try out your code tomorrow. Like Patrice's work your work has also stood out to me over the years And I thank you for coming to my aid here!!! Graphics really isn't something I've ever spent much time on so it is awesome to be able to get assistance from coders like yourself who've masterminded these fields, and I take my hat off to people like you and Patrice for their contributions in this field (your name regularly pops up on POFFS)

    Leave a comment:


  • José Roca
    replied
    Then he can try the following functions:

    Code:
    DECLARE FUNCTION GdipCreateBitmapFromFile LIB "GDIPLUS.DLL" ALIAS "GdipCreateBitmapFromFile" ( _
       BYVAL STRING _                           ' GDIPCONST WCHAR *filename
     , BYREF DWORD _                            ' GpBitmap **bitmap
     ) AS LONG                                  ' GpStatus
    
    DECLARE FUNCTION GdipCreateHBITMAPFromBitmap LIB "GDIPLUS.DLL" ALIAS "GdipCreateHBITMAPFromBitmap" ( _
       BYVAL DWORD _                            ' GpBitmap *bitmap
     , BYREF DWORD _                            ' HBITMAP *hbmReturn
     , BYVAL DWORD _                            ' ARGB background
     ) AS LONG                                  ' GpStatus
    Code:
    DIM hr AS LONG
    DIM strFileName AS STRING
    DIM pBitmap AS DWORD
    DIM hBitmap AS DWORD
    
    strFilename = UCODE$(<file name>)
    hr = GdipCreateBitmapFromFile (strFileName, pBitmap)
    hr = GdipCreateHBITMAPFromBitmap (pBitmap, hBitmap, 0)

    Leave a comment:


  • jcfuller
    replied
    Originally posted by José Roca View Post
    See: http://www.powerbasic.com/support/pb...ad.php?t=23625

    Use the function ConvertImgToBmp.
    José,
    It appears this just converts file to file. I believe he wants the bmp in memory?

    James

    Leave a comment:


  • José Roca
    replied
    See: http://www.powerbasic.com/support/pb...ad.php?t=23625

    Use the function ConvertImgToBmp.

    Leave a comment:


  • Tyrone W. Lee
    replied
    FreeImage

    I use FreeImage.DLL (Free Image Reader Library) to do all of my graphics conversions. It works really great, and did I mention... Its free!!

    http://freeimage.sourceforge.net/

    Here is the routine I used to load images from FreeImage and convert to Windows bitmaps. (This routines does a bit more but you can probably strip out what you need from it. Basically the last 12- 15 lines are your critical functions.)

    Code:
    FUNCTION PBSetBitmapBits(BYVAL PBBits AS INTEGER, BYVAL hBitmap AS LONG, BYVAL Src AS DWORD) AS LONG
        LOCAL ok AS LONG, success AS LONG
        LOCAL hdcBMP AS LONG
        LOCAL oldHnd AS LONG, bufSize AS LONG
        LOCAL SrcBuffer AS DWORD
    
        ON ERROR RESUME NEXT                       
    
        hdcBMP = GETDC(hBitmap)
        IF hdcBMP = %NULL THEN
        	hdcBMP = CREATEDC("DISPLAY", "", "", BYVAL 0&)
        END IF                                           
        ok = GetObject (hBitmap, LEN(CurrentBMP), CurrentBMP)
    
        oldHnd = SelectObject(hdcBMP, hBitmap)
        Set_DIBTileHeader PBBits, ABS(CurrentBMP.bmWidth), ABS(CurrentBMP.bmHeight)
    
        IF Src = %NULL THEN
            bufSize = ABS(CurrentBMP.bmHeight * CurrentBMP.bmWidth * INT(PBBits/8)) - LEN(CurrentBMPBits)
            IF bufSize > 0 THEN
                CurrentBMPBits = CurrentBMPBits + SPACE$(bufSize)
            END IF
            SrcBuffer = STRPTR(CurrentBMPBits)
        ELSE
            SrcBuffer = Src
        END IF
    
        success = SETDIBITS(BYVAL hdcBMP, BYVAL hBitmap, BYVAL 0, BYVAL ABS(CurrentBMP.bmHeight), BYVAL SrcBuffer, CurrentBMI, BYVAL %DIB_RGB_COLORS)  
        ok = SELECTOBJECT(hdcBMP, oldHnd) : ok = DELETEDC(hdcBMP)
    
        FUNCTION = success
    END FUNCTION
    
    FUNCTION GetBMPResource (BYVAL hBitmap AS LONG, BYVAL bmType%, BYVAL bmpWidth AS LONG , BYVAL bmpHeight AS LONG) EXPORT AS LONG
        LOCAL hBMP AS LONG
        LOCAL ok AS LONG, Create%
        LOCAL ScreenDC AS LONG
        LOCAL retVal AS LONG
    
        Create% = %True
        IF hBitmap <> %NULL THEN
            ok = GetObject (hBitmap, LEN(CurrentBMP), CurrentBMP)
            IF bmpWidth <> CurrentBMP.bmWidth OR bmpHeight <> CurrentBMP.bmHeight THEN
                Create% = %True
            ELSE
                retVal = hBitmap
                Create% = %False
            END IF
            IF (bmType% = 1 AND CurrentBMP.bmBitsPixel <> 1) OR (bmType% <> 1 AND CurrentBMP.bmBitsPixel = 1) THEN
                Create% = %True
            END IF
        END IF
    
        IF Create% = %True THEN
            IF hBitmap <> %NULL THEN ok = DeleteObject (hBitmap)
    
            SELECT CASE bmType%
                CASE 1
                    hBMP = CreateBitmap(bmpWidth, bmpHeight, 1, 1, BYVAL %NULL)
    
                CASE %NULL
                    ScreenDC = CreateDC("DISPLAY", "", "", BYVAL 0&)
                    hBMP = CreateCompatibleBitmap(ScreenDC, bmpWidth, bmpHeight)
                    ok = DeleteDC (ScreenDC)
    
                CASE ELSE
                    hBMP = CreateBitmap(bmpWidth, bmpHeight, 1, bmType%, BYVAL %NULL)
            END SELECT
            retVal = hBMP
        END IF
        FUNCTION = retVal
    END FUNCTION
    
    
    FUNCTION LoadGraphic(gfxFile$, BYVAL frmt AS INTEGER, BYVAL sFrame AS INTEGER, BYVAL eFrame AS INTEGER) AS LONG
        LOCAL retVal AS LONG, resFile$, OK AS LONG
        LOCAL Pic AS BitmapInfoType
        LOCAL bmpX AS LONG, bmpY AS LONG
        LOCAL fiBMP AS LONG, fiBMP24 AS LONG
        LOCAL fiWidth AS LONG, fiHeight AS LONG
        LOCAL bmpFile$, bmpExt$, bmpDel AS INTEGER
    
        ON ERROR RESUME NEXT
        bmpFile$ = gfxFile$   
        IF DOSFileExists(bmpFile) = %False THEN
    	    IF DumpResource(GetFileFromPath$(bmpFile$)) = %True THEN
    	        bmpDel = %True
    	        bmpFile$ = Program_Path$ + "TEMP\" + GetFileFromPath$(gfxFile$)
    	    END IF
    	END IF
    	
        bmpExt$ = UCASE$(FileExtension$(bmpFile$))
        SELECT CASE bmpExt$
            CASE "GFX"
                vbGetGFXInfo bmpFile$, Pic
                retVal = GetBMPResource(retVal, frmt, Pic.pWidth, Pic.pHeight)
                PBLoadGFXImage bmpFile$, retVal
    
            CASE "CLP"
                vbGetCLPInfo bmpFile$, Pic
                retVal = GetBMPResource(retVal, frmt, Pic.pWidth, Pic.pHeight)
                IF sFrame <= 0 AND eFrame <= 0 THEN
                    eFrame = INT(Pic.pWidth / Pic.FrameWidth) * INT(Pic.pHeight / Pic.FrameHeight)
                    retVal = PBLoadAnimClip(bmpFile$, retVal, 0, eFrame - 1, 1)
                ELSE
                    retVal = PBLoadAnimClip(bmpFile$, retVal, sFrame, eFrame, 1)
                END IF
    
            CASE "HDR"
                fiBMP = FreeImage_Load(%FIF_HDR, BYCOPY bmpFile$, %HDR_DEFAULT)
            CASE "GIF"
                fiBMP = FreeImage_Load(%FIF_GIF, BYCOPY bmpFile$, %GIF_DEFAULT)
            CASE "ICO"
                fiBMP = FreeImage_Load(%FIF_ICO, BYCOPY bmpFile$, %ICO_DEFAULT)
            CASE "BMP"
                fiBMP = FreeImage_Load(%FIF_BMP, BYCOPY bmpFile$, %BMP_DEFAULT)
            CASE "WBMP"
                fiBMP = FreeImage_Load(%FIF_WBMP, BYCOPY bmpFile$, %WBMP_DEFAULT)
            CASE "JPG", "JIF"
                fiBMP = FreeImage_Load(%FIF_JPEG, BYCOPY bmpFile$, %JPEG_ACCURATE)
     [B]       CASE "PNG"
                fiBMP = FreeImage_Load(%FIF_PNG, BYCOPY bmpFile$, %PNG_DEFAULT)[/B]
            CASE "JNG"
                fiBMP = FreeImage_Load(%FIF_JNG, BYCOPY bmpFile$, %JPEG_DEFAULT)
            CASE "PCX"
                fiBMP = FreeImage_Load(%FIF_PCX, BYCOPY bmpFile$, %PCX_DEFAULT)
            CASE "TIFF"
                fiBMP = FreeImage_Load(%FIF_TIFF, BYCOPY bmpFile$, %TIFF_DEFAULT)
            CASE "TARGA"
                fiBMP = FreeImage_Load(%FIF_TARGA, BYCOPY bmpFile$, %TARGA_DEFAULT)
            CASE "XPM"
                fiBMP = FreeImage_Load(%FIF_XPM, BYCOPY bmpFile$, %XPM_DEFAULT)
    
            CASE "RES"
                retVal = LoadBitmap(GetModuleHandle(""), BYCOPY GetFileFromPath$(bmpFile$))
        END SELECT
    
        IF bmpDel = %True THEN KILL bmpFile$
    
       [B] SELECT CASE bmpExt$
            CASE "BMP", "JPG", "JIF", "PNG", "HDR", "ICO", "WBMP", "JNG", "PCX", "TIFF", "TARGA", "XPM"'
                FreeImage_FlipVertical fiBMP
                fiBMP24 = FreeImage_ConvertTo24Bits(fiBMP) : FreeImage_Unload fiBMP
    
                fiWidth = FreeImage_GetWidth(fiBMP24)
                fiHeight = FreeImage_GetHeight(fiBMP24)
    
                retVal = GetBMPResource(retVal, %NULL, fiWidth, fiHeight)
                ok = PBSetBitmapBits(24, retVal, BYVAL FreeImage_GetBits(fiBMP24))
                FreeImage_Unload fiBMP24
        END SELECT[/B]
    
        FUNCTION = retVal
    END FUNCTION

    The GetBMPResource will create a bitmap when needed. It will resize bitmap space and make sure everything is "cleaned up" without memory leaks. It can create color or monochrome bitmaps.

    The PBSetbitmap Bits is the "re-creation" of the Windows SetbitmapBits using the SetDIBits() function. Microsoft deprecated the SetBitmapBits command, which was very easy & straight-forward. SetDIBits() is a little more difficult to use so I made this function to keep my brain from cramping.

    NOTE: Ignore any CLIP/GFX file functions. These are for my game engine's proprietary graphics formats.

    Good luck! And fee free to check me out!

    http://www.explore-rpg.com/cgi-bin/f...1206582666/8#8
    Last edited by Tyrone W. Lee; 2 May 2008, 07:28 AM.

    Leave a comment:


  • GDI+ ... how to load a non-BMP image ie PNG/JPG and convert it to a BMP?

    Hey guys,
    I have a GDI+ related problem thats been doing my head in all day and despite going through various GDI+ samples from our beloved Poffs I'm still none the wiser as to how to go about this as i have very little experience with GDI+. (I think Patrice could probably do this in his sleep)

    Basically, I have a PNG file, and I need to convert that to a BITMAP, and do this all in memory - I have no need to display the image, as all I want to do is analyse the image contents - basically I just want to look at the pixels in memory.

    Is GDI+ the right way to go about this, and if so does anybody know how on earth to do it !?

    Thanks
Working...
X