Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Load a Bitmap from a file (char array) stored in memory?

Load a Bitmap from a file (char array) stored in memory?

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsdata-structuresperformancehelpquestion
10 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Cyrilix
    wrote on last edited by
    #1

    I'm not sure how I should go about approaching this problem, but is there any way to create a bitmap by loading a "file in memory"? Let me explain. So, I initially have an encrypted .bmp on disk, that I load into a std::ifstream, decrypt, and dump back out to a char*. The char array essentially contains the entire file, character by character, meaning that if I were to dump it to an std::ofstream, I would get the decrypted version of the file I loaded into the std::ifstream (which would also happen to be a bitmap that I can view with any picture viewer). The problem is, I want to generate a bitmap from this "file in memory" stored as a char* and all the functions I know of either require a file name, or require loading it from an executable resource. The end result should be a Win32 BITMAP object. Is there any way of doing what I'd like to do? Thanks.

    L 1 Reply Last reply
    0
    • C Cyrilix

      I'm not sure how I should go about approaching this problem, but is there any way to create a bitmap by loading a "file in memory"? Let me explain. So, I initially have an encrypted .bmp on disk, that I load into a std::ifstream, decrypt, and dump back out to a char*. The char array essentially contains the entire file, character by character, meaning that if I were to dump it to an std::ofstream, I would get the decrypted version of the file I loaded into the std::ifstream (which would also happen to be a bitmap that I can view with any picture viewer). The problem is, I want to generate a bitmap from this "file in memory" stored as a char* and all the functions I know of either require a file name, or require loading it from an executable resource. The end result should be a Win32 BITMAP object. Is there any way of doing what I'd like to do? Thanks.

      L Offline
      L Offline
      led mike
      wrote on last edited by
      #2

      See if this helps[^]

      C 1 Reply Last reply
      0
      • L led mike

        See if this helps[^]

        C Offline
        C Offline
        Cyrilix
        wrote on last edited by
        #3

        This might work. I'm not inherently familiar with some of the parameters that have to be passed in, but I think I'll manage (and post back if I have issues). Thanks again!

        M 1 Reply Last reply
        0
        • C Cyrilix

          This might work. I'm not inherently familiar with some of the parameters that have to be passed in, but I think I'll manage (and post back if I have issues). Thanks again!

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          Cyrilix wrote:

          I'm not inherently familiar with some of the parameters that have to be passed in

          Here's a clue... The first structure is a BITMAPFILEHEADER[^]. You'll find an offset to the pixel data there. Following that is a BITMAPINFO[^] structure, within which you'll find a BITMAPINFOHEADER[^] structure. Bitmap Storage[^]

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          C 1 Reply Last reply
          0
          • M Mark Salsbery

            Cyrilix wrote:

            I'm not inherently familiar with some of the parameters that have to be passed in

            Here's a clue... The first structure is a BITMAPFILEHEADER[^]. You'll find an offset to the pixel data there. Following that is a BITMAPINFO[^] structure, within which you'll find a BITMAPINFOHEADER[^] structure. Bitmap Storage[^]

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            C Offline
            C Offline
            Cyrilix
            wrote on last edited by
            #5

            I've been looking around for code examples and trying to figure out the concepts in my head, and somehow, I think I'm using the wrong function (CreateDIBitmap) for what I want to do, since I have to pass in a device context. From what I've read, the device context is like a drawing surface, but I have no need for a drawing surface, since I don't actually plan on drawing the bitmap to a window. All I want to do is get a BITMAP which can then have its pixels altered (which in my mind, would mean setting bits contained in my BITMAP.bmBits structure to different values). What do you guys think? Am I just really confused or onto something? To clarify, my plan was the following: -Load encrypted file and store it as an encrypted memory stream -Decrypt memory stream and convert to BITMAP type -Do image processing on BITMAP type -Convert BITMAP back to a decrypted memory stream and encrypt -Save encrypted memory stream to file

            M 1 Reply Last reply
            0
            • C Cyrilix

              I've been looking around for code examples and trying to figure out the concepts in my head, and somehow, I think I'm using the wrong function (CreateDIBitmap) for what I want to do, since I have to pass in a device context. From what I've read, the device context is like a drawing surface, but I have no need for a drawing surface, since I don't actually plan on drawing the bitmap to a window. All I want to do is get a BITMAP which can then have its pixels altered (which in my mind, would mean setting bits contained in my BITMAP.bmBits structure to different values). What do you guys think? Am I just really confused or onto something? To clarify, my plan was the following: -Load encrypted file and store it as an encrypted memory stream -Decrypt memory stream and convert to BITMAP type -Do image processing on BITMAP type -Convert BITMAP back to a decrypted memory stream and encrypt -Save encrypted memory stream to file

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #6

              If you're going to manipulate the pixel data directly, then you can use a DIBSection ("a DIB that applications can write to directly"). CreateDIBSection()[^] The passed DC can be NULL for DIB_RGB_COLORS bitmaps. If you don't use a file mapping to create the DIBSection, you'll need to copy the pixel bits from your array to the allocated pixel bits pointer. The number of bytes to copy can be determined something like the following (psudocode):

              LONG NumberOfPixelBytes;
              if (0 != BITMAPINFOHEADER.biSizeImage)
              NumberOfPixelBytes = BITMAPINFOHEADER.biSizeImage;
              else
              NumberOfPixelBytes = (((BITMAPINFOHEADER.biWidth * (long)BITMAPINFOHEADER.biBitCount + 31L) & (~31L)) / 8L) * BITMAPINFOHEADER.biHeight;

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              C 1 Reply Last reply
              0
              • M Mark Salsbery

                If you're going to manipulate the pixel data directly, then you can use a DIBSection ("a DIB that applications can write to directly"). CreateDIBSection()[^] The passed DC can be NULL for DIB_RGB_COLORS bitmaps. If you don't use a file mapping to create the DIBSection, you'll need to copy the pixel bits from your array to the allocated pixel bits pointer. The number of bytes to copy can be determined something like the following (psudocode):

                LONG NumberOfPixelBytes;
                if (0 != BITMAPINFOHEADER.biSizeImage)
                NumberOfPixelBytes = BITMAPINFOHEADER.biSizeImage;
                else
                NumberOfPixelBytes = (((BITMAPINFOHEADER.biWidth * (long)BITMAPINFOHEADER.biBitCount + 31L) & (~31L)) / 8L) * BITMAPINFOHEADER.biHeight;

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                C Offline
                C Offline
                Cyrilix
                wrote on last edited by
                #7

                Hi Mark, I've got a good idea of how to do this when it comes to initially loading the Bitmap. The only other issue I have is saving the Bitmap back. My impression is that from an HBITMAP that is returned from CreateDIBSection(), we can get a BITMAP by calling GetObject() in such a manner:

                HBITMAP hBmp = CreateDIBSection(...);
                BITMAP bmp;
                GetObject(hBmp, sizeof(bmp), &bmp);

                But, the BITMAP object itself does not seem to have enough information to recreate the BITMAP file. For instance, from the MSDN documentation, it states that BITMAP has the following members:

                LONG bmType;
                LONG bmWidth;
                LONG bmHeight;
                LONG bmWidthBytes;
                WORD bmPlanes;
                WORD bmBitsPixel;
                LPVOID bmBits;

                The BITMAP file specification, on the other hand, has (as your link described):

                BITMAPFILEHEADER:
                WORD bfType;
                DWORD bfSize;
                WORD bfReserved1;
                WORD bfReserved2;
                DWORD bfOffBits;

                BITMAPINFO:
                RGBQUAD bmiColors[1];

                BITMAPINFOHEADER (inside BITMAPINFO):
                DWORD biSize;
                LONG biWidth;
                LONG biHeight;
                WORD biPlanes;
                WORD biBitCount;
                DWORD biCompression;
                DWORD biSizeImage;
                LONG biXPelsPerMeter;
                LONG biYPelsPerMeter;
                DWORD biClrUsed;
                DWORD biClrImportant;

                RGBQUAD array: data that has to do with palettes

                Color-index array: the raw image data itself

                If you compare the two lists, it would seem like BITMAP contains enough information to recreate most of the variables in BITMAPINFOHEADER as well as the info needed for the color-index array, but what about the rest of the info? It would seem like if I'm trying to convert it back to a char array, I would have to do some fancy extrapolation myself, in addition to saving some of the info that I had when I loaded the image. I will have another careful look at all of the BITMAP related functions to see if I've missed something, but at the moment, I'm sort of stuck at this point. Also, if I haven't mentioned it to you yet, your advice so far been much appreciated.

                M 1 Reply Last reply
                0
                • C Cyrilix

                  Hi Mark, I've got a good idea of how to do this when it comes to initially loading the Bitmap. The only other issue I have is saving the Bitmap back. My impression is that from an HBITMAP that is returned from CreateDIBSection(), we can get a BITMAP by calling GetObject() in such a manner:

                  HBITMAP hBmp = CreateDIBSection(...);
                  BITMAP bmp;
                  GetObject(hBmp, sizeof(bmp), &bmp);

                  But, the BITMAP object itself does not seem to have enough information to recreate the BITMAP file. For instance, from the MSDN documentation, it states that BITMAP has the following members:

                  LONG bmType;
                  LONG bmWidth;
                  LONG bmHeight;
                  LONG bmWidthBytes;
                  WORD bmPlanes;
                  WORD bmBitsPixel;
                  LPVOID bmBits;

                  The BITMAP file specification, on the other hand, has (as your link described):

                  BITMAPFILEHEADER:
                  WORD bfType;
                  DWORD bfSize;
                  WORD bfReserved1;
                  WORD bfReserved2;
                  DWORD bfOffBits;

                  BITMAPINFO:
                  RGBQUAD bmiColors[1];

                  BITMAPINFOHEADER (inside BITMAPINFO):
                  DWORD biSize;
                  LONG biWidth;
                  LONG biHeight;
                  WORD biPlanes;
                  WORD biBitCount;
                  DWORD biCompression;
                  DWORD biSizeImage;
                  LONG biXPelsPerMeter;
                  LONG biYPelsPerMeter;
                  DWORD biClrUsed;
                  DWORD biClrImportant;

                  RGBQUAD array: data that has to do with palettes

                  Color-index array: the raw image data itself

                  If you compare the two lists, it would seem like BITMAP contains enough information to recreate most of the variables in BITMAPINFOHEADER as well as the info needed for the color-index array, but what about the rest of the info? It would seem like if I'm trying to convert it back to a char array, I would have to do some fancy extrapolation myself, in addition to saving some of the info that I had when I loaded the image. I will have another careful look at all of the BITMAP related functions to see if I've missed something, but at the moment, I'm sort of stuck at this point. Also, if I haven't mentioned it to you yet, your advice so far been much appreciated.

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #8

                  Cyrilix wrote:

                  from an HBITMAP that is returned from CreateDIBSection(), we can get a BITMAP by calling GetObject() in such a manner:

                  No need to make it that complicated - just keep the original headers! All the info you need is there. You're only changing the pixels, right?

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  C 1 Reply Last reply
                  0
                  • M Mark Salsbery

                    Cyrilix wrote:

                    from an HBITMAP that is returned from CreateDIBSection(), we can get a BITMAP by calling GetObject() in such a manner:

                    No need to make it that complicated - just keep the original headers! All the info you need is there. You're only changing the pixels, right?

                    Mark Salsbery Microsoft MVP - Visual C++ :java:

                    C Offline
                    C Offline
                    Cyrilix
                    wrote on last edited by
                    #9

                    Well, in a sense, that's true, but I'd also like to handle the case where I've gotten a BITMAP from somewhere else (i.e., just been passed a BITMAP from another function), and I'm asked to save it. Is that not possible to implement easily?

                    M 1 Reply Last reply
                    0
                    • C Cyrilix

                      Well, in a sense, that's true, but I'd also like to handle the case where I've gotten a BITMAP from somewhere else (i.e., just been passed a BITMAP from another function), and I'm asked to save it. Is that not possible to implement easily?

                      M Offline
                      M Offline
                      Mark Salsbery
                      wrote on last edited by
                      #10

                      Cyrilix wrote:

                      Is that not possible to implement easily?

                      BMP bitmaps are the easiest format to save. The Bitmap Storage[^] shows the layout of the file. Another option: If you're not into writing the code yourself, and you can use an ATL class, the CImage class[^] is a nice lightweight wrapper around a DIBSecion bitmap and will load and save in other formats beyond BMP. The member functions make it easy to do all the things you've discussed so far.

                      Mark Salsbery Microsoft MVP - Visual C++ :java:

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups