Announcement

Collapse
No announcement yet.

How to write a Bitmap to a file?

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

  • How to write a Bitmap to a file?

    In my PBDLL60 program I have created a bitmap whose handle is hBmp.
    I would like to write it to a file "linear.bmp". In Petzold's book I found functions that I thought should be applicable here.
    These functions are shown below.

    //LOCAL Bm as BITMAP

    GETOBJECT hBmp,SIZEOF(Bm),Bm
    count&=bm.bmWidthBytes*bm.bmHeight*bm.bmPlanes
    GetBitmapBits hBmp,count&,pbuffer
    hDCMEM&=CreateFile("linear.bmp",%generic_write,0,BYVAL %null,%create_always,0,0)
    hDCMEMM&=WriteFile(hDCMEM&,pbuffer,count!,count1!,%null)

    GETOBJECT retrieves the bitmap's information.
    It is surprising, however, that Bm.bmBits is zero.
    It seems that I have a problem with pbuffer in function GetBitmapBits.
    I am not sure what this parameter should be.
    I dimensioned a string and got pbuffer as VARPTR(), but it does not work.
    The program crashes at GetBitmapBits function.

    By the way, the bitmap is OK - I copy it to the screen.

    How can I achieve my goal?
    Could, please, somebody help me with this problem?

    Edmund

    [email protected]




    ------------------

  • #2
    The first thing to check is the API function return values - one of these API's is probably failing, but this code is not detecting it.

    If you can locate which API is failing, you'll be ½ way to solving the problem!

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      According to MSDN:
      "The GetBitmapBits function is not implemented in the Win32 API.
      This function is provided for compatibility with 16-bit versions of Windows.
      Win32-based applications should use the GetDIBits function."

      Regards
      Peter


      ------------------

      Comment


      • #4
        edmund --
        i guess, that you need dib section (then it's necessary to add a header only).
        there is one trick, which is used, for example, in http://www.powerbasic.com/support/pb...ad.php?t=17640

        1) to create 32-bits dib section with the same sizes as a picture.
        to select it into temporary hdc (lets name it hdc1)
        2) to select real hbmp to another hdc (hdc2)
        3) bltbit hdc2 -> hdc1




        ------------------

        Comment


        • #5
          Thank you Lance, Peter and Semen for your kind responses.

          Lance, as I mentioned in my post, GetBitmapBits hBmp,count&,pbuffer function is failing.
          However, Peter mentioned, this function should rather be replaced by the GetDIBits function.
          I have also tried to use:
          ...
          ...
          ...
          DIM buff AS STRING buffer=VARPTR(buff)
          GETOBJECT hBmp,SIZEOF(Bm),VARPTR(Bm) 'LOCAL Bm as BITMAP
          count&=bm.bmWidthBytes*bm.bmHeight*bm.bmPlanes
          i&=GetDIBits(hDc,hBmp1,bm.bmHeight-1,bm.bmHeight,pbuffer,BYVAL VARPTR(Bm),%DIB_RGB_COLORS)

          hDCMEM&=CreateFile("linear.bmp",%generic_write,0,BYVAL %null,%create_always,0,0)
          hDCMEMM&=WriteFile(hDCMEM&,pbuffer,count!,count1!,ByCopy %null)

          The bitmap whose handle is hBmp does exist - I am putting it on a dialog - and
          GETOBJECT retrieves the bitmap's information (though Bm.bmBits is zero).
          However, GetDIBits doesn't work since the function returns zero (i&=0).
          Moreover, the compiler does not like WriteFile function.
          Regardless of whether I have 'ByCopy %null' or only '%null' I get a message that it should be 'ByCopy %null'.

          Unfortunately, I haven't found any examples on how to write a bitmap to a file either in Petzold's book or on the forums.

          Semen, I have tried your suggestions to create o copy of a bitmap.
          I have had no problems with that, but I have failed as far as writing this copy to a file is concerned.
          Do you have, by any chance, a piece of code that could help me in this regard?

          I hope someone has a piece of relevant code involving writing a bitmap with a known handle
          to a file that could be made available to amateurs like myself. I would appreciate this very much.

          With thanks and kind regards,

          Edmund

          ------------------

          Comment


          • #6
            Edmund --
            I have such piece inside one utility and it's necessary to clean it.
            (probably, I will do it in nearest days - just now no time).
            But general scheme is following.
            For 24-bit BMP it's not necessary to fill RGBQUAD.
            So it's necessary to prepare (some statements only)
            BITMAPFILEHEADER (14 bytes) + BITMAPINFOHEADER (40 bytes)
            After this you should copy bits of DIB (1 : 1).

            I don't know, how you want to use BMP-file, but if you plan
            to transfer it to picture editor, there is alternative way - to copy hBmp to clipboard.
            It's also some statements and I posted a code on Source code forum about 2-3 monthes ago.

            ------------------

            Comment


            • #7
              Semen brings up a good point... The bitmap header information has to be formatted differently, depending on to color resolution of the system at runtime. GetDIBits will return a different format for each color depth (24 bit, 16, bit, etc.) and your function will need to be aware of that.

              Not only that, but certain incompatabilities exist between bitmap formats, and sometimes you have to "convert" the data to make it useable by another system. For example, a 24-bit bitmap created on my NT system will not display on my 95 test system unless the bits are "massaged" before the file is saved. The problem is caused by a fairly common video driver issue -- the GetDIBits function is actually executed by the video driver so it is not the most consistent API function in the world -- and a generic save-bitmap function has to be aware of a couple of those.

              My general point is that there are many hidden complications. Edmund, are you trying to create a program for your own use, or a program that will need to work on a number of different machines?

              -- Eric

              ------------------
              Perfect Sync: Perfect Sync Development Tools
              Email: mailto:[email protected][email protected]</A>



              [This message has been edited by Eric Pearson (edited July 02, 2000).]
              "Not my circus, not my monkeys."

              Comment


              • #8
                Look at this URL

                It is C code, but easy to translate to PB

                http://codeguru.earthweb.com/bitmap/index.shtml

                ------------------
                Patrice Terrier
                mailto[email protected][email protected]</A>
                Patrice Terrier
                www.zapsolution.com
                www.objreader.com
                Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                Comment


                • #9
                  Eric --
                  A trick with dummy DIB-section - see my link, posted above -
                  allows to avoid GetDIBits' difficultes.
                  Results doesn't depend of current color depth.



                  ------------------

                  Comment


                  • #10
                    Semen --

                    Your CreateDIBSection technique looks interesting. Next time I'm working with graphics I'll take a more serious look at it. Have you tested it when the screen is using various color depths?

                    -- Eric

                    ------------------
                    Perfect Sync: Perfect Sync Development Tools
                    Email: mailto:[email protected][email protected]</A>

                    "Not my circus, not my monkeys."

                    Comment


                    • #11
                      Eric --
                      > Have you tested it when the screen is using various color depths?
                      Yes, because I try to support pallette.
                      I posted on Source code forum two samples, where is used this technique.
                      (transparent bitmaps & bitmap to region).
                      Note only, that to avoid any risk it's better to add
                      GlobalLock/GlobalUnlock hBmp of DIB-section.

                      But it's not my technique. I took it from Codeguru samples (see Patrice's link).


                      ------------------

                      Comment


                      • #12
                        > to avoid any risk it's better to add GlobalLock/GlobalUnlock

                        And GdiFlush, according to Win32.HLP.

                        -- Eric

                        ------------------
                        Perfect Sync: Perfect Sync Development Tools
                        Email: mailto:[email protected][email protected]</A>

                        "Not my circus, not my monkeys."

                        Comment


                        • #13
                          Thanks, Semen, Eric, and Patrice for your kind responses and valuable tips.

                          Semen, I have tried your code posted to the Source Code Forum on my machine under Widows 95.
                          It works without any problems. I used also the part of this code that pertains to writing of a BMP to a file.
                          It works also. Semen, you are an angel!
                          I looked at the C++ function related to the matter which I found on the site recommended by Patrice, but I doubt I would be able to figure out how to make use of it.
                          But owing to you I do not have to do so. Thanks again - I am really very much obliged to you.

                          Kind regards to everyone,

                          Edmund

                          ------------------

                          Comment


                          • #14
                            I have done some more testing of the procedure developed with the kind help of Semen.
                            I think, Eric, that the results of these tests may be of interest to you also.
                            But first maybe I should explain why I was bothering you with this problem.

                            I am using your Graphics Tools, Eric, to produce graphs of the results of the engineering analysis that my program performs.
                            I use two tabs, on one of which a piece-wise linear graph appears and on the other one a qubic spline graph is displayed.
                            To be able to toggle these two graphs, I copy one to the clipboard usig the Graphics Tools and then make a copy this image and put it on the dialog of the first tab.
                            There is no problem with the second graph - it is created one time and used as many times as the user wants.
                            Generally, this works fine. Moreover, the clipboard copy can be easily pasted into a MSWord 97 document and the size of this document is only 34kB!
                            I found also, that MSWord 97 refuses to make use of the image sved to a BMP file, although the MSPaint accepts this file without any problems.
                            Furthermore, this file is a huge one, having 2785 kB!
                            I didn't want to mention this before since this could sound as a criticism of Graphics Tools.
                            But I like Graphics Tools, and I think this is a feature of Windows (I use Windows 95).
                            That's why I wanted to explore this option of making a file copy of the Clipboard image.
                            And indeed, the file based on this image is smaller by 700kB, and moreover, it is being read by MSWord 97 without any problems!
                            I do not know if the same would apply to other OS systems and to other versions of Word.
                            But if this is, indeed, the case then, I think, it is better to use the Clipboard BMP image to create a BMP file.

                            Thanks guys for the kind and prompt help rendered to me,

                            Regards,

                            Edmund

                            ------------------

                            Comment


                            • #15
                              Edmund --

                              Your numbers are confusing me a bit, but I think I understand what is going on.

                              > the clipboard copy can be easily pasted into a
                              > MSWord 97 document and the size of this document
                              > is only 34kB!

                              Well, a Word 97 document containing just the word "Test" is 19k, so IMO it's pretty unlikley that you could really add a 2.75 meg high-resolution bitmap and end up with a 34k file. I just did a PrintScreen to capture my desktop to a bitmap, and I pasted it into a Word doument. I have to admit that I was surprised when the doc file only grew to 52k, but then I used Word's "zoom" feature to blow up the resulting document. The bitmap image was very blurry, indicating that Word had converted the image format to a much lower quality.

                              I then used Explorer's View/Refresh function to re-check the size of the doc file, and it had magically grown to over 220k. I haven't looked closely at this, but it sure looks to me like Microsoft is playing games when you save a Word 97 file. The Explorer display is not being updated normally, even after you close Word.

                              > I found also, that MSWord 97 refuses to make use
                              > of the image sved to a BMP file,

                              I had no problem using Word's Insert/Picture/From File feature to add TrueColor bitmaps (created by Graphics Tools) to a Word document. If you can give me an example that fails, I will be very glad to look at it. As I mentioned in an earlier message, formatting bitmap files can be very tricky, so Graphics Tools may be producing an image format that Word can't handle.

                              > Furthermore, this file is a huge one, having 2785 kB!

                              If your monitor is using the 24-bit TrueColor mode, that would be a bitmap of approximately 960 by 960 pixels. TrueColor 24-bit bitmaps require 3 bytes (24 bits) per pixel. That's a requirement of the file format. A bitmap file is literally a map of the bits in an image, so in most cases each pixel in the image will require a certain, fixed number of bits or bytes in the file, and there's not much that can be done about it.

                              I just pasted that same PrintScreen image into Paint and saved the file, and the file size was 1,322,454 bytes. The image was 800 by 551 pixels, and 800 * 551 * 3 bytes/pixel = 1,322,400. Add 54 bytes for the bitmap file header, and the numbers match exactly.

                              > ...making a file copy of the Clipboard image
                              > ...the file based on this image is smaller by 700kB

                              I'll have to look into this in more detail, but here is what I believe is going on. When you place a bitmap image into the clipboard, you can use the clipboard's auto-format conversion function and retrieve the data in a different format. Windows is probably performing Run Length Encoding (RLE) on the image, and producing an RLE bitmap. Depending on a bitmap's contents, RLE can produce a very high image compression ratio (i.e. it can make the file very small) or it can produce no compression at all. 700k out of 2,785k (about 25%) is very believable.

                              The problem with RLE bitmaps is that not all versions of Windows, and not all programs, handle them correctly. Heck, many programs can't handle all of the non-RLE bitmap formats properly! While developing Graphic Tools we created dozens of bitmap files using each of the six different bitmap formats (1/4/8/16/24/32 bits). We then tried to load them into a variety of programs that can use bitmaps. I don't have the results "log" in front of me, but we saw a large number of random failures. Maybe 15% overall. Some programs could load every bitmap we created, but some (like Netscape) did not like certain standard formats. They either did not display, or they came out with distored colors. PhotoShop, on the other hand, loaded them all flawlessly. The shareware bitmap viewers that we tested had the worst track record. We eventually located a "bitmap checker" program and we were able to confirm that we were in fact producing all six bitmap file formats correctly.

                              By the way, not even Windows itself had a 100% track record. The Windows 95 API, for example, cannot load certain types of 32-bit bitmaps. (Graphics Tools automatically "patches" those files so that Windows 95 can load them.) Note also that Microsoft Paint cannot create RLE bitmaps, which is an indication of the level of RLE support that Microsoft provides.

                              Another problem with RLE is that Windows only "formally" supports RLE compression of 4- and 8-bit bitmaps, and not many people use the 16-color and 64k-color resolutions any more. TrueColor (24/32) is far more common.

                              Yet another problem is the complexity of performing bit-level RLE encoding. Performing RLE encoding at the 4-bit level is fairly complicated, and quite slow, and there is a corresponding slowdown when they are loaded by Windows. Not only that, but 4-bit (16-color) bitmaps are very small to begin with! That same 1.3 meg bitmap bitmap would be just 220k in the 16 color format, without using RLE compression. Does that need to be compressed further? Adding 25% compression would only gain you about 55k.

                              In the end, the technique that is used to produce a bitmap (using the clipboard vs. the way Graphics Tools does) it is irrelevant. A certain-format bitmap file will be a certain size, period. TANSTAAFL. You can use a different file format, but there are problems with doing so.

                              Here is the bottom line, from where we sit. Non-RLE-encoded bitmaps are the "gold standard" of Windows image formats. They are supported directly by the Windows operating system, and virtually every program that supports images in any way supports non-RLE bitmaps. (As I said, however, even that support is not perfect.) When you begin using other formats like RLE-encoded bitmaps, GIF, JPEG, etc. etc. etc. the level of acceptance and reliability drops dramatically. So we decided that Graphics Tools would only produce 100%-standard non-RLE bitmaps, so that we would not be responsible for compatability problems. You can use an external package (like the one that smalleranimals.com distrubutes) to change the image format, but you do so at your own risk.

                              -- Eric

                              P.S. I will try to find some time to investigate whether or not Windows "informally" supports 32-bit RLE encoding, as your numbers seem to imply, or if something else is really going on.

                              ------------------
                              Perfect Sync: Perfect Sync Development Tools
                              Email: mailto:[email protected][email protected]</A>



                              [This message has been edited by Eric Pearson (edited July 03, 2000).]
                              "Not my circus, not my monkeys."

                              Comment


                              • #16
                                In MSDN look at this one:

                                HOWTO: Capture and Print the Screen, a Form, or any Window
                                ID: Q161299

                                There are some stuffs that could be usefull to you.

                                ------------------
                                Patrice Terrier
                                mailto[email protected][email protected]</A>

                                [This message has been edited by Patrice Terrier (edited July 03, 2000).]
                                Patrice Terrier
                                www.zapsolution.com
                                www.objreader.com
                                Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                                Comment


                                • #17
                                  Except OLE

                                  ------------------

                                  Comment


                                  • #18
                                    Thanks, Eric, for the response.
                                    You are absolutely right that there are plenty of problems with the bitmaps.
                                    In the meantime I have tried to further explore the problem, and I must admit I have become even more confused.
                                    I have found that on other machines, also under Windows 95, there are no problems to use (in Word 6) the bitmaps created by Graphics Tools by direct writing to a file.
                                    Of course I use "Insert Picture from File", and on my machine I get a message that "An error occurred while importing this file".
                                    As for the sizes of the images obtained in the different ways mentioned in my previous post, they also differ on different machines (for the same resulution).
                                    This must depend upon the colors (video card?).
                                    You mentioned a poor quality of the image based on the clipboard content obtained in Word.
                                    In my case, the quality of this image seems to be as good as that based on the big BMP file.
                                    This, probably, depends on the complexity of the area captured.
                                    In my case, the area captured is a very simple one. White background and color lines and markers.
                                    I must also add that the BMP file based on the clipboard content and obtained with the aid of MsPaint is almost as big as the one created by Graphics Tools by direct writing to a file.
                                    The quality of the print copy of any of the bitmaps is also quite good.

                                    In the light of what we have found, I think there is no need to waste time on further investigation of the matter, since the results of such are heavily dependent on the system and the software used.

                                    Patrice, thanks for your tip - I will look at that.

                                    Regards,

                                    Edmund

                                    ------------------

                                    Comment


                                    • #19
                                      Edmund --

                                      > I use "Insert Picture from File", and
                                      > on my machine I get a message that "An
                                      > error occurred while importing this file".

                                      I never see that. Which color depth was used to create the bitmap? In other words, which color setting was your monitor using (16 bit, 24-bit TrueColor, etc.) when you created the bitmap? If you'd like to send me the file, I'll be very glad to take a look at it. It could be that your video card/driver is producing an unusual format, and that Graphics Tools could be modified to compensate for it.

                                      > they also differ on different machines (for
                                      > the same resulution). This must depend upon
                                      > the colors (video card?).

                                      Yes, it depends on the color depth setting of the monitor when the bitmap is created. The math isn't straightforward because the bitmap header format varies depending on the color depth, but in rough terms each pixel in the bitmap will account for x bits in the file. If the bitmap is a 24-bit bitmap, each pixel will require 24 bits (3 bytes) in the file. If you're curious, the bytes are Red, Green, and Blue values from 0-255 each, for a total of 16 million possible colors. If the bitmap is an 16-bit bitmap, each color gets 5 bits (values 0-31) and the last bit in each word is wasted, yielding a total of 32k possible colors. (Some video drivers use the last bit to get 64k colors out of 16 bits, but that is not a standard format.)

                                      > You mentioned a poor quality of the image
                                      > based on the clipboard content obtained in
                                      > Word. In my case, the quality of this image
                                      > seems to be as good as that based on the big
                                      > BMP file.

                                      To be clear, the image in the clipboard is perfect. But when Word imports it, Word apparently uses an image format with lower resolution than the original. I can see the effect very clearly if I use the View/Zoom/Percent setting to blow up the document to 400% or so, and compare it to some nearby text. The edges of the text are very sharp, but the bitmap appears to have been heavily aliased, resulting in a blurry effect.

                                      > The quality of the print copy of any of the
                                      > bitmaps is also quite good.

                                      That's because most printers can't approach the resolution that would be needed to see individual pixels in everyday situtations, i.e. large bitmaps printed small. That's almost certainly why Word uses the lower-resolution image format... It doesn't make any difference in the end product. But you probably would not want to save an image in that format for generic use, because the image degradation would be obvious in other situations.

                                      -- Eric


                                      ------------------
                                      Perfect Sync: Perfect Sync Development Tools
                                      Email: mailto:[email protected][email protected]</A>

                                      "Not my circus, not my monkeys."

                                      Comment


                                      • #20
                                        Edmund,
                                        Perhaps Word 97 would perform better if the graph were converted to
                                        a Windows Metafile. I used this format with Visual Tools First Impression and
                                        VB. It seemed to work better with Word 6.0 than the BMP file, plus it was sizeable.

                                        You could test this quickly if you have access to a graphics program such as Paint Shop Pro.
                                        If you don't, send me a copy of the BMP and I will test it for you.

                                        Also, I think there was a metafile sample in the source code forum recently.

                                        Scott
                                        [email protected]

                                        ------------------


                                        [This message has been edited by Scott Hauser (edited July 04, 2000).]
                                        The most exasperating part of the "rat race" is how often the rats are in the lead!

                                        Comment

                                        Working...
                                        X