Bitmap bitmap file reading, saving, and screenshots

Source: Internet
Author: User
Tags fread

Although there are already many bitmap reading and saving articles on the Internet, many of which are detailed and provide powerful source code functions, I still need to rewrite a bitmap loading program myself. The main reason is that these articles are too esoteric and the code functions are so powerful that cainiao like me cannot read them. Therefore, I want to be concise. Omit some details, such as the palette. For ease of operation, my program only supports loading of more than 24 bitmap files.

First, understand the structure of the bitmap file. A 24-Bit Bitmap File consists of three parts: bitmapfileheader, bitmapinfoheader, and bitmap data.

The following are the definitions of two information headers in msdn:

Typedef struct tagbitmapfileheader {word bftype; // image type: It must be 'bm '(The hexadecimal code of BM is 0x4d42) DWORD bfsize; // The offset from the beginning of the file to the data. That is, the bitmapfileheader structure and the bitmapinfoheader size word bfreserved1; // reserved value. It must be 0 word bfreserved2; // reserved value. It must be 0 DWORD bfoffbits; // file size. Contains two structures and the total data size .} Bitmapfileheader, * pbitmapfileheader; typedef struct tagbitmapinfoheader {DWORD bisize; // the size of the current struct. Long biwidth; // The width of the bitmap. The Unit is long biheight; // The height of the bitmap. The Unit is pixel word biplanes; // Number of Bitmap planes. It must be the number of digits of the 1 word bibitcount // bitmap, that is, the bitmap depth. It can be 1, 4, 8, 16, 24, and 32. Bitmap files with less than 16 bits contain information about the color palette. DWORD bicompression; // compression method. The bitmap is not compressed, and the bi_rgb parameter (that is, 0) is assigned ). DWORD bisizeimage; // The number of bytes occupied by bitmap data. The default value is 0. Long bixpelspermeter; // specify the horizontal resolution of the target device. The unit is the number of pixels per meter. It can be set to 0 long biypelspermeter; // specify the vertical resolution of the target device, as shown in the preceding figure. DWORD biclrused; // specify the pixels actually used by the image. You can set it to 0 DWORD biclrimportant; // specify the number of important colors of the image. It can be set to 0, indicating that all colors are important .} Bitmapinfoheader, * pbitmapinfoheader;


The following figure shows the bitmap data:

The bitmap is stored by row. The bitmap width is not equal to the number of row bytes of the bitmap. Each pixel occupies bibitcount/8 bytes, and the number of bytes occupied by each row must be an integer multiple of 4 bytes! For example, for bitmap 101*101*24, the number of bytes occupied by rows is: 101*3 = 303, and 303% 4! = 0, so the number of bytes occupied by the row needs to be modified to 304. the actual size of the bitmap data is 304*101, and the bisizeimage above can be set to 304*101.

The following is an example of structure filling for storing bitmap files:

Bitmapfileheader bmheader; memset (& bmheader, 0, sizeof (bmheader); bmheader. bftype = 0x4d42; // image format. It must be in 'bm 'format. Bmheader. bfoffbits = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader); // The offset from the beginning of the file to the data bmheader. bfsize = m_nwidthbytes * m_nheight + bmheader. bfoffbits; // file size bitmapinfoheader bminfo; memset (& bminfo, 0, sizeof (bminfo); bminfo. bisize = sizeof (bminfo); bminfo. biwidth = m_nwidth; bminfo. biheight = m_nheight; bminfo. biplanes = 1; bminfo. bibitcount = m_ndeep; bminfo. bicompression = bi_rgb;

Note: m_nwidthbytes can be calculated as follows: int m_nwidthbytes = (m_nwidth * m_ndeep/8 + 3)/4) * 4;

The following is an API used to create a DIB bitmap and obtain the hbitmap handle.

HBITMAP CreateDIBSection(
  HDC hdc,                 // handle to DC
  CONST BITMAPINFO *pbmi,  // bitmap data
  UINT iUsage,             // data type indicator
  VOID **ppvBits,          // bit values
  HANDLE hSection,         // handle to file mapping object
  DWORD dwOffset           // offset to bitmap bit values
);

(Here is not detailed introduction, you can go to the encyclopedia to see, such as: http://www.hudong.com/wiki/CreateDIBSection)


Let's roughly describe the process of opening a file:

1. Read the bitmapfileheader data of the file header.

2. Read bitmapinfoheader data.

3. Read bitmap data.

4. Use createdibsection to create a DIB bitmap and copy the read data to the DIB bitmap.

Then you can use the DIB bitmap handle to perform bitmap operations.


File saving process:

1. Fill in the file header bitmapfileheader and write it to the file.

2. Fill in the Bitmap header bitmapinfoheader and write it to the file.

3. Obtain bitmap data (getbitmapbits, or record the data address when createdibsection) and write the data to the file.


Function (see the end of the article for reference examples ):

1. Create a mask DC (createcompatibeldc), a mask Bitmap (createcompatiblebitmap), and select the bitmap to the DC.

2. Copy the DC content of the window to the mask DC (that is, copy it to the mask Bitmap ).

3. Next we will talk about the process of saving files.



Attachment: I encapsulate the above operations.

// Dibbitmap. h # pragma onceclass cdibbitmap {public: // method cdibbitmap (void );~ Cdibbitmap (void); bool create (HDC, int width, int height, int deep); // create a bitmap bool create (HDC, hbitmap ); // create a bitmap bool load (HDC, char * szfilename) by copying; // save (char * szfilename) from the bitmap bool ); // Save the bitmap to the file void clear (void); // clear the data void samplerender (HDC, int X, int y); // simple display public: // properties // obtain the bitmap inline hbitmap getbitmap (void) {return m_hdibbmp;} // obtain the data inline byte * getbmp data (void) {return m_pbm Pdata;} // obtain the width inline int getwidth (void) {return m_nwidth;} // obtain the height inline int getheight (void) {return m_nheight ;} // obtain the bit depth inline int getdeep (void) {return m_ndeep;} // obtain the number of bytes in a row inline int getwidthbytes (void) {return m_nwidthbytes;} protected: // member hbitmap m_hdibbmp; byte * m_pbmpdata; // point to the bitmap data int m_nwidth; // width. (Unit: pixel) int m_nheight; // height. Pixel int m_ndeep; // depth. Bit. The depth must be greater than 24-bit int m_nwidthbytes; // The number of bytes required for a row. It must be an integer multiple of 4 bytes .};

// Dibbitmap. CPP # include <windows. h> # include <stdio. h> # include "dibbitmap. H "////////////////////////////////////// /// // cdibbitmap:: cdibbitmap (void) {m_hdibbmp = NULL; m_pbmpdata = NULL; m_nwidth = 0; // width. (Unit: pixel) m_nheight = 0; // height. Pixel m_ndeep = 0; // depth. Bit. The depth must be greater than 24 bits m_nwidthbytes = 0;} cdibbitmap ::~ Cdibbitmap (void) {clear ();} bool cdibbitmap: Create (HDC, int width, int height, int deep) {clear (); m_nwidth = width; m_nheight = height; m_ndeep = deep; bitmapinfo bminfo; memset (& bminfo, 0, sizeof (bminfo); bminfo. bmiheader. bisize = sizeof (bminfo); bminfo. bmiheader. biwidth = m_nwidth; bminfo. bmiheader. biheight = m_nheight; bminfo. bmiheader. biplanes = 1; bminfo. bmiheader. bibitcount = m_ndeep; bminfo. Bmiheader. bicompression = bi_rgb; m_hdibbmp = createdibsection (HDC, & bminfo, dib_rgb_colors, (void **) & m_pbmpdata, null, 0); If (m_hdibbmp = NULL) {return false ;} m_nwidthbytes = (m_nwidth * m_ndeep/8 + 3)/4) * 4; return true;} bool cdibbitmap: Create (HDC, hbitmap) {If (null = HDC | null = hbitmap) {return false;} // obtain bitmap information. Bitmap bm; GetObject (hbitmap, sizeof (BM), & BM ); // create a bitmap if (! Create (HDC, BM. bmwidth, BM. bmheight, BM. bmbitspixel) {return false;} // obtain hbitmap data and copy it to the DIB bitmap getbitmapbits (hbitmap, BM. bmwidthbytes * BM. bmheight, getbmp data (); Return true;} void cdibbitmap: clear (void) {If (m_hdibbmp! = NULL) {deleteobject (m_hdibbmp);} m_hdibbmp = NULL; m_pbmpdata = NULL;} void cdibbitmap: samplerender (HDC, int X, int y) {HDC memdc = createcompatibledc (0); SelectObject (memdc, m_hdibbmp); bitblt (HDC, X, Y, m_nwidth, m_nheight, memdc, 0, 0, srccopy ); deletedc (memdc);} bool cdibbitmap: load (HDC, char * szfilename) {file * fp = NULL; fopen_s (& FP, szfilename, "rb "); if (null = FP) {return false;} // read the file header Bitmapfileheader bmheader; If (fread (& bmheader, sizeof (bmheader), 1, FP )! = 1) {fclose (FP); Return false;} // read bitmap information header bitmapinfoheader bminfo; If (fread (& bminfo, sizeof (bminfo), 1, FP )! = 1) {fclose (FP); Return false;}/* Note: currently, the program does not support bitmap loading of color palette data. */If (bminfo. bibitcount <16) {return false;} // create a DIB bitmap if (! Create (HDC, bminfo. biwidth, bminfo. biheight, bminfo. bibitcount) {fclose (FP); Return false;} // read bitmap data if (fread (m_pbmpdata, m_nwidthbytes, m_nheight, FP )! = M_nheight) {fclose (FP); Return false;} fclose (FP); Return true;} bool cdibbitmap: Save (char * szfilename) {If (null = m_hdibbmp | null = m_pbmpdata) {return false;} file * fp = NULL; fopen_s (& FP, szfilename, "WB "); if (null = FP) {return false;} bitmapfileheader bmheader; memset (& bmheader, 0, sizeof (bmheader); bmheader. bftype = 0x4d42; // image format. It must be in 'bm 'format. Bmheader. bfoffbits = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader); // The offset from the beginning of the file to the data bmheader. bfsize = m_nwidthbytes * m_nheight + bmheader. bfoffbits; // file size bitmapinfoheader bminfo; memset (& bminfo, 0, sizeof (bminfo); bminfo. bisize = sizeof (bminfo); bminfo. biwidth = m_nwidth; bminfo. biheight = m_nheight; bminfo. biplanes = 1; bminfo. bibitcount = m_ndeep; bminfo. bicompression = bi_rgb; If (fwrite (& bmhe Ader, sizeof (bmheader), 1, FP )! = 1) {fclose (FP); Return false;} If (fwrite (& bminfo, sizeof (bminfo), 1, FP )! = 1) {fclose (FP); Return false;} For (INT I = m_nHeight-1; I> = 0; -- I) {int Index = m_nwidthbytes * I; if (fwrite (m_pbmpdata + index, m_nwidthbytes, 1, FP )! = 1) {fclose (FP); Return false ;}} fclose (FP); Return true ;} //////////////////////////////////////// //////////////////////////////////

Function reference code:

// Obtain the device description table m_hdevicecontext = getdc (m_hwnd); // create mask = createcompatibledc (m_hdevicecontext); // create mask bitmap m_bbackbitmap = mask (m_hdevicecontext, m_nwidth, m_nheight ); selectObject (m_hbackdc, m_bbackbitmap );... copy the content of m_hdevicecontext to m_hbackdc using bitblt... cdibbitmap BMP; If (! BMP. Create (m_hbackdc, m_bbackbitmap) {g_log.write ("failed! ");} Else {createdirectory (text (" shot "), null); char buffer [64]; systemtime TM; getlocaltime (& TM); sprintf_s (buffer, 64, "Shot/mongod_mongod_mongod_mongod_mongod_mongod.bmp", TM. wyear, TM. wmonth, TM. wday, TM. whour, TM. wminute, TM. wsecond); If (! BMP. Save (buffer) {g_log.writex ("failed to save the bitmap [% s! ", Buffer );}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.