Announcement

Collapse
No announcement yet.

Read/Using/Writing Image Formats Other Than BMP

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

  • Gary Beene
    replied
    Egads!

    This post from Nov 2009 shows how quickly time gets away from me.
    Anyway, I decided this was the week to dedicate time to GDI and GDI+.
    Here it is 2011 and while I've work with GDI a fair amount, it's 2011 and I still haven't wrapped my arms around GDI+.

    Seriously, this is the week ... ... and I still have all of these posts to guide me!

    Leave a comment:


  • José Roca
    replied
    Next step: Direct2D

    Direct2D is a hardware-accelerated, immediate-mode, 2-D graphics API that provides high performance and high-quality rendering for 2-D geometry, bitmaps, and text. The Direct2D API is designed to interoperate well with GDI, GDI+, and Direct3D.

    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx

    I have began to update my headers to Windows 7 and, among other goodies, they will include support for Direct2D.

    Again, M$ has managed to make the documentation worthless for non C++ programmers by using some wrapper classes and using a C++ syntax. Remember the times when the examples were in plain ansi C?

    Leave a comment:


  • Barry Marks
    replied
    I've been doing a little bit of what Gary is doing with GDI+. The function posted earlier worked just fine but I needed a little more so I looked at other related functions in Jose Roca's site and I've been using other functions as well.

    I think when I first looked at it a few months ago I was overwhelmed by the lack of an entry point for me. What I found were a huge number of descriptions of functions and structures and I had no idea what was what. Jumping into that would take a week just to find a realistic starting point.

    I did try reading some of Microsoft's docs on GDI+ last time but I get lost in their verbosity. I've always found their reference material useful and their explanations unreadable. If I was an OOP programmer I might have found some kind of meaningful overview but as it was I have no idea if I found an overview or not.

    As Gary said, this loader gave me a starting point. I still want to pretty much stick with DDT and keep things simple, but I guess I do need to step outside it at timees.

    Anyway, thank you guys very much for this and related threads here lately. I've learned a lot and it's gotten me started in some useful stuff.

    Barry

    Leave a comment:


  • José Roca
    replied
    tb_gdiplus is an older translation that I did for pre-PBWin 9.0 compilers. The ones integrated in my Windows API headers are more current (updated to GDI+ 1.1) and require the use of my headers for supporting streams.

    "tb_" is a prefix I was using mainly for my libraries of COM wrapper functions for older versions of PB and comes from TypeLib Browser (I used this tool to write the wrappers).

    Attachements are only visible to registered users because, unfortunately, the SMF forum software doesn't allow to show them disabled.

    Leave a comment:


  • Brice Manuel
    replied
    tb=Thin BASIC?

    I believe you have to be a logged in user to download from that link.
    Oh well.

    Leave a comment:


  • Mike Doty
    replied
    I believe you have to be a logged in user to download from that link.
    I don't know what the tb_ is for either?


    Jose's site: http://www.jose.it-berater.org
    Forum logon: http://www.jose.it-berater.org/smfforum/index.php
    The functions: http://www.jose.it-berater.org/gdiplus/iframe/index.htm

    GdiPlus include: tb_gdiplus.zip http://www.jose.it-berater.org/smffo...php?topic=88.0

    Join the forum, it is great and free.
    Last edited by Mike Doty; 19 Nov 2009, 11:36 AM.

    Leave a comment:


  • Brice Manuel
    replied
    Is there an actual URL to download the zip?

    Leave a comment:


  • Gary Beene
    replied
    Hi Mike,

    By masterpiece, I assume you meant the entire Roca site? I'd have to agree that the site is awesome - lots of depth. I've not spent near enough time there to understand what all is there, much less to extract all the information relevant to my needs.

    BTW, what does the tb_ refer to in the zip file?
    Last edited by Gary Beene; 19 Nov 2009, 11:24 AM.

    Leave a comment:


  • Mike Doty
    replied
    Jose, you were posting at the same time.
    I can't see using google and reading 70,000 pages, sorry Michael.

    I would rather read Jose's translations!
    I hope everyone realizes this is a masterpiece.

    Jose's site: http://www.jose.it-berater.org
    Forum logon: http://www.jose.it-berater.org/smfforum/index.php
    The functions: http://www.jose.it-berater.org/gdiplus/iframe/index.htm

    GdiPlus include: tb_gdiplus.zip http://www.jose.it-berater.org/smffo...php?topic=88.0

    Last edited by Mike Doty; 19 Nov 2009, 11:07 AM.

    Leave a comment:


  • José Roca
    replied
    Gary,

    The first, sticky post in the subforum devoted to GDI+

    http://www.jose.it-berater.org/smffo...p?topic=1832.0

    lists three skeletons (for SDK, DDT and DDT Graphic Control) that shows the basic steps.

    I also have a reference guide for GDI

    http://www.jose.it-berater.org/gdi/iframe/index.htm

    because GDI+ does not replace GDI, but extends it.

    GDI is also a huge API.

    Learn it at your own pace. Just don't discard it because they're API functions instead of PB statements.

    Leave a comment:


  • Michael Mattias
    replied
    When a topic is large (600+ GDI+ functions), it's nice to have something that allows us to ease into the uncharted waters
    Google==>
    Results 1 - 10 of about 72,400 English pages for books about gdi+. (0.31 seconds)

    Leave a comment:


  • Gary Beene
    replied
    I would agree:

    It would be a shame to use GDI+ only to load the image
    The thing about the loader code is that it's a very useful introduction to GDI+. When a topic is large (600+ GDI+ functions), it's nice to have something that allows us to ease into the uncharted waters - bite-sized chunks to swallow rather than an entire ocean.

    Once the introductory code becomes a regular part of a programmer's apps, I think it will only be natural (and much more comfortable) to add more and more GDI+ functions. The first thing you know, GDI+ isn't such a strange beast - it's a valued close friend.

    I know with API I started the same way. A few useful ones, then another, then another - now it's old hat. I expect to grow into using GDI+ in the same way. I'm an enormous fan of using built-in features, so I'm look at using an external DLL like freeimage.dll as a last ditch effort - unless the external tool offers some very specific advantages (ease of use, feature set, ...) . Hence, my pleasure at seeing some very useful GDI+ starter code that will encourage me to dig deeper.
    Last edited by Gary Beene; 19 Nov 2009, 10:06 AM.

    Leave a comment:


  • José Roca
    replied
    Question - does the GDI+ determine the size of the image (from the file) and create a full-sized image/graphic object accordingly?

    I assume that the GDI+ puts as much of the image (from the file) into the target hDC as will fit, so it is up to me to make my Graphic Target large enough to fit the full image available from the file.
    If you look at my reference guide ( http://www.jose.it-berater.org/gdiplus/iframe/index.htm ) you will see that there are several GdipDrawImageXXX functions. GdipDrawImageRect allows to specify the left/top position and also the width and height. And there are others, such GdipDrawImageRectRect, GdipDrawImagePoints and GdipDrawImagePointsRect.

    It would be a shame to use GDI+ only to load the image because, with more that 600 functions, and in combination with GDI, it provides everything you need. Although, contrarily to Patrice, I'm not a graphics guy and I know little about the subject, I did see the importance of this API. There are more than 300 examples in my forum, illustrating the use of almost any function. Because the examples provided by M$ are written using C++ wrapper classes, instead of the flat API, I have listed in the examples both the C++ code and my PB translation to help the readers to understand what the C++ code really does. The examples also show the documentation of the function as a web page inside a frame in the post and a capture displaying the result, and the code includes SDK and DDT versions.

    I also wrote an image control that uses GDI+ ( http://www.jose.it-berater.org/smffo...p?topic=3138.0 ) and, because I'm a SDK programmer and PB's graphic control can't be used with SDK, a graphic control that can be used with GDI and GDI+, and with SDK and DDT (although, of course, you can't use PB's GRAPHIC statetements with it): http://www.jose.it-berater.org/smffo...p?topic=2868.0

    Paradoxically, I have received more feedback from users of other languages (even ansi C programmers) than from PBer's. A PureBasic programmer used my reference guide to write its own (in French): http://purebasic.developpez.com/tuto...documentation/
    Last edited by José Roca; 19 Nov 2009, 09:24 AM.

    Leave a comment:


  • Gary Beene
    replied
    Jose,

    It's amazing how once a person gets to looking in detail at a topic, the more they understand information they've already read but didn't understand the first time they read it (that would be me).

    I had seen your post here:

    http://www.powerbasic.com/support/pb...GDIP_DrawImage

    But at the time I didn't recognize it for the value it contains - essentially the answer to my question on this thread - which you have kindly restated for me in this thread - without letting me know I'm a dummy for not having understood/used code you've already posted.

    Sometimes a person just has to be ready to listen before the knowledge will sink in.

    Thanks for your patience.
    Last edited by Gary Beene; 19 Nov 2009, 05:51 AM.

    Leave a comment:


  • Gary Beene
    replied
    Jose,
    Thank you for the clarification.

    Question - does the GDI+ determine the size of the image (from the file) and create a full-sized image/graphic object accordingly?

    I assume that the GDI+ puts as much of the image (from the file) into the target hDC as will fit, so it is up to me to make my Graphic Target large enough to fit the full image available from the file.

    ... and BTW, I tested the code using a memory bitmap instead of a graphic control and it also worked just fine.

    Life is good!
    Last edited by Gary Beene; 19 Nov 2009, 12:21 AM.

    Leave a comment:


  • José Roca
    replied
    BTW, did you notice that I had to replace STRPTR (as your original code listed) with just the string variable in this line:
    That is because the parameter is declared as BYVAL STRING in Patrice's translation and as BYVAL DWORD in my translation. I have used BYVAL DWORD for consistency with the thousands of functions and methods in my Windows API headers that have unicode string parameters.

    Leave a comment:


  • Gary Beene
    replied
    Jose,

    I didn't catch that the code put the image into the graphic target, so I added the Graphic Copy. The code worked with that line in it, but only by luck of the draw. I've removed it.

    The Control Redraw was the key point that I didn't think of. The fact that the image displayed on startup led me to thinking something not-so-trivial was at fault. Once that line was added, all was well.

    BTW, did you notice that I had to replace STRPTR (as your original code listed) with just the string variable in this line:

    Code:
    '  hStatus = GdipLoadImageFromFile(StrPTR(strFileName), pImage) ' Create the Image object
    On compile, I got a message saying a string was needed so when I placed the string variable in the call, the compile error went away and the code worked.


    Thanks very much, Jose! The resulting Function will be very useful to me.

    Here's the corrected code, which seems to work just great.

    Code:
    'Compilable Example:
    'Credit: Jose Roca
    #Compile Exe
    #Dim All
    #Include "Win32API.inc"
    #Include "includes\GDIPLUS.INC"
    Global hDlg as DWord
    %IDC_GRAPHIC1  = 101
    %IDC_GRAPHIC2  = 102
    %IDC_GRAPHIC3  = 103
    
    Function PBMain() As Long
       Dialog New Pixels, 0, "GDI+ Load Image Test",300,300,500,200, %WS_OverlappedWindow To hDlg
       Control Add Button, hDlg, 110,"GIF", 10,10,60,20
       Control Add Button, hDlg, 120,"BMP", 100,10,60,20
       Control Add Button, hDlg, 130,"JPG", 190,10,60,20
       Control Add Graphic, hDlg, %IDC_GRAPHIC1, "",  20, 40, 125, 125   ' Add a graphic control
       Control Add Graphic, hDlg, %IDC_GRAPHIC2, "", 170, 40, 125, 125   ' Add a graphic control
       Control Add Graphic, hDlg, %IDC_GRAPHIC3, "", 320, 40, 125, 125   ' Add a graphic control
       Dialog Show Modal hDlg Call DlgProc
    End Function
    CallBack Function DlgProc() As Long
       If CB.Msg = %WM_Command Then
          Select Case CB.Ctl
             Case 110
                 LoadImage_GDIP "garyface.gif", %IDC_Graphic1
                 Control Redraw hDlg, %IDC_Graphic1
             Case 120
                 LoadImage_GDIP "cowgirl.bmp", %IDC_Graphic2
                 Control Redraw hDlg, %IDC_Graphic2
             Case 130
                 LoadImage_GDIP "daniel.jpg", %IDC_Graphic3
                 Control Redraw hDlg, %IDC_Graphic3
          End Select
       End If
    End Function
    
    Function LoadImage_GDIP(sFileName As String, targetID as Long) As Long
       Local hr As LONG, token AS DWord, hDC As DWord
       Local hStatus As LONG, pGraphics AS DWord, pImage As DWord
       Local StartupInput AS GdiplusStartupInput
    
       ' Initialize GDI+
       StartupInput.GdiplusVersion = 1
       hr = GdiplusStartup(token, StartupInput, BYVAL %NULL)
       If hr Then Function = 0 : Exit Function   'return 0 if fails
    
       Graphic Attach hDlg, targetID             ' Select the drawing target
       Graphic Get DC TO hdc                     ' Retrieve the handle of the device context
       Graphic Color %BLACK, %WHITE              ' Set the foreground and background color
       Graphic Clear                             ' Clear the entire selected graphic window
    
       sFileName = UCode$(sFileName)
       hStatus = GdipLoadImageFromFile(sFileName, pImage)           ' Create the Image object
       hStatus = GdipCreateFromHDC(hDC, pGraphics)                  ' Create the Graphic object
       hStatus = GdipDrawImage(pGraphics, pImage, 0, 0)             ' Draw the image
    
       If pImage Then GdipDisposeImage(pImage)                      ' Cleanup
       If pGraphics Then GdipDeleteGraphics(pGraphics)              ' Cleanup
       GdiplusShutdown token                                        ' Shutdown GDI+
    
       Function = 1                                                 ' Success
    End Function
    
    'gbs_00413
    I'll post this in the Source Code forum, with credit given to you, to make it easier for other folks to find.
    Last edited by Gary Beene; 18 Nov 2009, 11:33 PM.

    Leave a comment:


  • José Roca
    replied
    1. Remove Graphic Copy pGraphics, targetID. pGraphics is not an handle suitable to be used with GRAPHIC DDT statements. Besides isn't needed, since GdipDrawImage is who draws the image.

    2. Redraw the control with CONTROL REDRAW.
    Last edited by José Roca; 18 Nov 2009, 11:21 PM.

    Leave a comment:


  • Gary Beene
    replied
    Jose,
    Thanks for the code. The idea of loading a JPG/GIF/PNG into a control so that I can use GRAPHIC statements is exactly what I was requesting.

    However, using your code as a guide, I created a function that I thought I could call at any time. But when I run an application the function only works if I load the images before I show the dialog.

    Is there a limitation to the code example you gave, such that after the dialog is shown the images cannot be loaded? Or perhaps I just haven't applied the code correctly into a Function.

    Here's the function, followed by the compilable example. In this version, I assume that a Graphic Control is the target.

    Code:
    Function LoadImage_GDIP(sFileName As String, targetID as Long) As Long
       Local hr As LONG, token AS DWord, hDC As DWord
       Local hStatus As LONG, pGraphics AS DWord, pImage As DWord
       Local StartupInput AS GdiplusStartupInput
    
       ' Initialize GDI+
       StartupInput.GdiplusVersion = 1
       hr = GdiplusStartup(token, StartupInput, BYVAL %NULL)
       If hr Then Function = 0 : Exit Function   'return 0 if fails
    
       Graphic Attach hDlg, targetID             ' Select the drawing target
       Graphic Get DC TO hdc                     ' Retrieve the handle of the device context
       Graphic Color %BLACK, %WHITE              ' Set the foreground and background color
       Graphic Clear                             ' Clear the entire selected graphic window
    
       sFileName = UCode$(sFileName)
    '  hStatus = GdipLoadImageFromFile(StrPTR(strFileName), pImage) ' Create the Image object
       hStatus = GdipLoadImageFromFile(sFileName, pImage)           ' Create the Image object
       hStatus = GdipCreateFromHDC(hDC, pGraphics)                  ' Create the Graphic object
       hStatus = GdipDrawImage(pGraphics, pImage, 0, 0)             ' Draw the image
    
       Graphic Copy pGraphics, 0                                           ' put image in target
    
       If pImage Then GdipDisposeImage(pImage)                      ' Cleanup
       If pGraphics Then GdipDeleteGraphics(pGraphics)              ' Cleanup
    '   GdiplusShutdown token                                        ' Shutdown GDI+
       Function = 1                                                 ' Success
    End Function
    And here's the compilable example. Note that if I call the image loading function before the dialog is shown, all works well. But if I call the function after the dialog is shown (by pressing one of the buttons), the function does not show the image.

    You'll have to use your own image. Also, note that I'm using the gdiplus.inc file that Patrice posted. I haven't yet done a wholesale replacement of the PowerBASIC includes with the ones I downloaded from you site.

    Code:
    'Compilable Example:
    'Credit: Jose Roca
    #Compile Exe
    #Dim All
    #Include "Win32API.inc"
    #Include "includes\GDIPLUS.INC"
    Global hDlg as DWord
    %IDC_GRAPHIC1  = 101
    %IDC_GRAPHIC2  = 102
    %IDC_GRAPHIC3  = 103
    
    Function PBMain() As Long
       Dialog New Pixels, 0, "GDI+ Load Image Test",300,300,500,200, %WS_OverlappedWindow To hDlg
       Control Add Button, hDlg, 110,"GIF", 10,10,60,20
       Control Add Button, hDlg, 120,"BMP", 100,10,60,20
       Control Add Button, hDlg, 130,"JPG", 190,10,60,20
       Control Add Graphic, hDlg, %IDC_GRAPHIC1, "",  20, 40, 125, 125   ' Add a graphic control
       Control Add Graphic, hDlg, %IDC_GRAPHIC2, "", 170, 40, 125, 125   ' Add a graphic control
       Control Add Graphic, hDlg, %IDC_GRAPHIC3, "", 320, 40, 125, 125   ' Add a graphic control
    
       LoadImage_GDIP "garyface.gif", %IDC_Graphic1
       LoadImage_GDIP "cowgirl.bmp", %IDC_Graphic2
       LoadImage_GDIP "daniel.jpg", %IDC_Graphic3
    
       Dialog Show Modal hDlg Call DlgProc
    End Function
    CallBack Function DlgProc() As Long
       If CB.Msg = %WM_Command Then
          Select Case CB.Ctl
             Case 110 : LoadImage_GDIP "garyface.gif", %IDC_Graphic1
             Case 120 : LoadImage_GDIP "cowgirl.bmp", %IDC_Graphic2
             Case 130 : LoadImage_GDIP "daniel.jpg", %IDC_Graphic3
          End Select
       End If
    End Function
    
    Function LoadImage_GDIP(sFileName As String, targetID as Long) As Long
       Local hr As LONG, token AS DWord, hDC As DWord
       Local hStatus As LONG, pGraphics AS DWord, pImage As DWord
       Local StartupInput AS GdiplusStartupInput
    
       ' Initialize GDI+
       StartupInput.GdiplusVersion = 1
       hr = GdiplusStartup(token, StartupInput, BYVAL %NULL)
       If hr Then Function = 0 : Exit Function   'return 0 if fails
    
       Graphic Attach hDlg, targetID             ' Select the drawing target
       Graphic Get DC TO hdc                     ' Retrieve the handle of the device context
       Graphic Color %BLACK, %WHITE              ' Set the foreground and background color
       Graphic Clear                             ' Clear the entire selected graphic window
    
       sFileName = UCode$(sFileName)
    '  hStatus = GdipLoadImageFromFile(StrPTR(strFileName), pImage) ' Create the Image object
       hStatus = GdipLoadImageFromFile(sFileName, pImage)           ' Create the Image object
       hStatus = GdipCreateFromHDC(hDC, pGraphics)                  ' Create the Graphic object
       hStatus = GdipDrawImage(pGraphics, pImage, 0, 0)             ' Draw the image
    
       Graphic Copy pGraphics, 0                                           ' put image in target
    
       If pImage Then GdipDisposeImage(pImage)                      ' Cleanup
       If pGraphics Then GdipDeleteGraphics(pGraphics)              ' Cleanup
       GdiplusShutdown token                                        ' Shutdown GDI+
       Function = 1                                                 ' Success
    End Function
    
    'gbs_00413
    Last edited by Gary Beene; 18 Nov 2009, 11:14 PM.

    Leave a comment:


  • José Roca
    replied
    Almost as an aside, I had an interesting revelation last night - discovering that I've mostly stayed away from examples which use INCLUDEs. I think that the hundreds of INCLUDE lines have somewhow made me think that although the example might work, that I wouldn't truly understand what was going on because I wasn't seeing the lines that were being pulled in - sometimes perhaps only a few lines. Somehow that translated into thinking that the example wasn't quite what I wanted.
    Putting everything in a post (constants, declares, code, error checking, etc.) makes it to look complex. I always try to make the examples short and clean. Then add you all the error checking code you wish.

    Leave a comment:

Working...
X