BMP and JPEG

Source: Internet
Author: User
BMP and JPEG
Author: Shu Rongwen
Date: 2016.5.29
1. What is BMP
The BMP format is the simplest and most intuitive bitmap data format. Its thought is very simple:
The information of a pixel is saved by a number of bits, and a pixel stream is formed by a number of pixels to express a picture.
Usually we will use 1 bits (can save 2 colors, 0 for one color, 1 for another, not necessarily black and white, or blue-green, anyway 2), 4-bit-16 colors, 8-bit-256 colors, 16-bit-65535 colors, 24-bit-2^24 colors, 32-bit-first 24-bit and 24-bit Bitmap can save 2^24 color, the last 8 bits to save the pixel's grayscale (that is, the degree of brightness of this pixel), can represent 256 shades of gray. Note that the current display can only support 24-bit colors on hardware, and Libjpeg can handle only a maximum of 24-bit color pixel streams.
For 24-bit BMP, a "palette" can be introduced to enhance the expressive ability of the image, with 8-bit, 256-color bitmap as an example:
In a 8-bit bitmap, the information for each pixel is stored in one byte, and the DIB data is a byte dibbuffer[] array, dibbuffer[0] represents the color of the first pixel, and so on. We know that the color is a combination of RGB 3 components, programming with the RGBQUAD structure, then 8 bits divided by 3, each component can only be stored with 2 bits (without encoding compression RLE), the actual performance of the color is very limited. Now we're introducing a rgbquad of length 256. An array of types: Rgbquad colortable[256], the color value of each pixel that we no longer directly store in the DBI array dibbuffer[], but the index of that color value in colortable, so that you can take advantage of Dibbuffer Storage space for each bit in the. This "colortable" is the concept of a palette in Windows. Knowing this, you can understand why bitmaps of 24-bit and darker-colored images do not need a palette.
2.1. BMP file format and DIB
The DIB is "device-independent bitmap" meaning, we can understand as a group of pixels, which is the data we need to process when programming, very simple, is a fixed-length array, if it is a 24-bit DIB data, then programming can be considered a BYTE dibbuffer[], DIBBUFFER[0],DIBBUFFER[2],DIBBUFFER[2] represents the RGB value of the first pixel (actually BGR), dibbuffer[3],[4],[5] represents the RGB value of the second pixel, and so on. Of course we can't just put this Dibbuffer arrays are written to disk as BMP files, missing picture palettes, wide, higher information, so we need a specific format to store the DIB pixel stream.
The BMP file format is the related convention that you need to follow to store the DIB pixel stream to disk. A detailed description of the BMP file format can be found on the Internet, for example, this article is very clear: http://blog.csdn.net/lanbing510/article/details/8176231
From a programmatic point of view, a BMP file can be expressed as the following structure:
typedef struct TAGBITMAP_FILE
{
Bitmapfileheader Bitmapheader;
Bitmapinfoheader Bitmapinfoheader;
PaletteEntry Palette[n]; Palette data (optional, the value of n is computed by bitmapfileheader::boffbits)
UCHAR *dibbuffer; DIB Data Array
} bitmap_file;
Details of the Bitmapfileheader, Bitmapinfoheader, paletteentry structure can be found in MSDN.
Describe briefly in natural language:
File header-fixed length, indicating that this file is a BMP file, version number, file length, etc., the most important when the file header structure of the Bfoffbits field, which represents the DIB pixel stream data in the file offset position, programming, we open a BMP file, first read the fixed-length file header, In this field you can construct the previously said palette array Rgbquad colortable[] and the DIB array BYTE dibbuffer[].
BMP information Header-fixed length, storing the width and high information of the bitmap, the field to be noted biheight, if it is a positive number, the information of the pixel stream is stored in reverse order, the pixels of the bottom row of the Ascension chart are stored in the front; if it is a negative number, the information for the pixel stream is stored in the Dibbuffer begins.
Palette array-optional, subtracting the length of the header and header from the offset address in the file header is the length of the palette array.
The DIB Pixel stream-is the dibbuffer[] array.
It is important to note that in real programming, the order in which 24-bit DIB data is stored is BGR (dibbuffer[0] is the B component of the first pixel in the last row, Dibbuffer[1] is the G component, Dibbuffer[2] is the R component, and JP G compression requires the input sequence is RGB, so the dibbuffer supplied to the JPEG compressor need to deal with, Dibbuffer[i] and Dibbuffer[i + 2] swap, otherwise the resulting JPG image color is not correct.
2.2. DDB
DDB is the meaning of "device-related bitmap", after the DIB data is written to the device, the device internally will be the DIB data processing as an internal format, Windows GDI with hbitmap expression of a DDB, we only need to invoke the relevant API on it, the details do not need to ignore.
3. What is JPEG
JPEG is a DIB data encoding rules, before we mentioned BMP file, directly to the DIB array dibbuffer[] directly to the file, so the BMP file is original, no loss of memory to save the image data. If an algorithm is used to compress the Dibbuffer array encoding, Then we may not need to write the entire dibbuffer (usually a large array) directly into the file, which can save disk space significantly. JPEG is such an algorithm.
4. Libjpeg
C language implementation of the JPEG library, website address: http://www.ijg.org/
4.1 Compiling
I write this article when the JPEG library version is jpeg-9b, from the official web download source Jpegsr9b.zip extracted, start visual Studio, enter the command line mode, switch to the JPEG source directory, input: nmake/f MAKEFILE.VC will see Jpeg.sln-vs The project file appears, open the compilation with visual Studio.
If you are prompted to not find the Win32.mak when you execute the NMAKE command, edit makefile.vc!include <win32.mak> comment out the 12th line, in fact nmake/f MAKEFILE.VC is not really compiled, this is Renamed a few files.
After the compilation is completed: Jpeg.lib This is the library file you need, and then Jconfig.h, Jerror.h, Jinclude.h, Jmorecfg.h, Jpeglib.h copied to your project even if the configuration is complete.
4.2 example.c
Libjpeg Use example in the source package of the example.c file, we just have to write_jpeg_file/read_jpeg_file two functions to understand the most applications can be dealt with.

4.3 Memory JPG Compression decompression and other
The instance in Example.c uses file Io, and the Jpeg_mem_src/jpeg_mem_dest function replaces the jpeg_stdio_src/jpeg_stdio_dest to implement memory IO.
JPEG libraries do not know the color palette and the like, it is simply the input of the DIB pixel stream compression output to a shorter output stream. So for BMP files that contain a palette, because the index number of the palette is saved in the DIB array and not the color value, it is submitted to the JPEG The library needs to construct a true DIB pixel stream with color information based on the palette, so that the JPEG library works correctly.
====================================================================================================
Appendix: Intercepting the Windows desktop and saving it as a. jpg file
int save_screen_to_jpeg (const char* filename, int quality) {/* * * Save the screen contents as a hbitmap DDB */HDC HSCRNDC = CreateDC (_t ("D    Isplay "), NULL, NULL, NULL); HDC HMEMDC = CreateCompatibleDC (HSCRNDC);    Get screen resolution int xscrn = GetDeviceCaps (HSCRNDC, horzres); int yscrn = GetDeviceCaps (HSCRNDC, vertres); Create a bitmap and check hbitmap hscrnbmp = CreateCompatibleBitmap (HSCRNDC, XSCRN, YSCRN); SelectObject (HMEMDC, hscrnbmp); Copy screen contents BitBlt (HMEMDC, 0, 0, XSCRN, YSCRN, HSCRNDC, 0, 0, srccopy); Now get a hbitmap ddb-hscrnbmp/* * Get DIB data through the hscrnbmp DDB *///Get color depth JPG can only handle 24-bit color, so regardless of the current system settings of the color depth is how much, we require getdibit The S function returns 24-bit DIB data and does not require a palette//int colordeepbits = GetDeviceCaps (hscrnbmp, Bitspixel); if (Colordeepbits >) colordeepbits = 24; int colordeepbits = 24; The number of bytes per row of pixels that are aligned to 4 bytes per line.  int imagerowsize = (XSCRN * colordeepbits + 31)/32 * 4; Assigning a DIB array unsigned char* dibbuffer = new unsigned char[imagerowsize * YSCRN]; ASSERT (Dibbuffer); memset (dibbuffer, 0, imagerowsize * yscrn); Clear Zerois a good habit//padding BMP information head bitmapinfo BMI = {0}; bmi.bmiHeader.biSize = sizeof (Bitmapinfoheader); Bmi.bmiHeader.biWidth = XSCRN;  Bmi.bmiHeader.biHeight = Yscrn *-1; JPG compression requires a positive sequence of DIB pixel streams, so negative numbers are required. Bmi.bmiHeader.biPlanes = 1; Bmi.bmiHeader.biBitCount = colordeepbits; Bmi.bmiHeader.biCompression = Bi_rgb; Gets the DIB array of pixels (dib_rgb_colors means to get an RGB value instead of a palette index, and of course a 24-bit bitmap does not have a palette) int gdiret = GetDIBits (HMEMDC, hscrnbmp, 0, YSCRN, Dibbuff Er, &bmi, dib_rgb_colors); ASSERT (Gdiret = = YSCRN); ASSERT (Bmi.bmiHeader.biSizeImage = = Imagerowsize * YSCRN); The DIB data has been obtained and all GDI objects can be freed. DeleteDC (HSCRNDC); DeleteDC (HMEMDC); DeleteObject (hscrnbmp); /* * To compress the DIB data into JPG data, the order of the colors in the EXAMPLE.C//DIB is BGR, and the JPG requirements are RGB, so we want to exchange R and B.//Because of the row alignment factor, the line-by-line processing for t row = 0; Row < YSCRN;  ++row) {unsigned char* rowdata = dibbuffer + imagerowsize * ROW;   for (int col = 0; col < xscrn * 3; col + + 3) {unsigned char swap = Rowdata[col];   Rowdata[col] = Rowdata[col + 2];  Rowdata[col + 2] = swap; }}//compress the bitmap data into JPEG struct jpeg_compress_struct cinfo; struct Jpeg_error_mgr jerr;  FILE * outfile; /* Target file */Jsamprow row_pointer[1];  /* Pointer to jsample row[s] */int row_stride; /* Physical row width in image buffer */int image_width = XSCRN; int image_height = YSCRN;     jsample* image_buffer = Dibbuffer; DIB buffer int Image_buffer_len = imagerowsize * image_height; DIB buffer Length if (fopen_s (&outfile, filename, "WB"))//if ((outfile = fopen_s (filename, "WB")) = = NULL) {fprintf (  stderr, "can ' t open%s\n", filename); ASSERT (0);  } else {/* Step 1:allocate and initialize JPEG compression Object */Cinfo.err = Jpeg_std_error (&jerr); /* Now we can initialize the JPEG compression object.  */jpeg_create_compress (&cinfo); /* Step 2:specify data destination (eg, a file) *///* Note:steps 2 and 3 can be do in either order.  */Jpeg_stdio_dest (&cinfo, outfile); /* Step 3:set parameters for compression */* First we supply a description of the INput image.  * Four fields of the cinfo struct must is filled in: */cinfo.image_width = image_width;  /* Image width and height, in pixels */cinfo.image_height = image_height;  Cinfo.input_components = 3;  /* # of color components per pixel *//Because the DIB data is 24 bits, each pixel occupies 3 bytes cinfo.in_color_space = Jcs_rgb;   /* ColorSpace of input image */* Now use the library's routine to set default compression parameters. * (You must set @ least cinfo.in_color_space before calling this, * since the defaults depend on the source color space   .)  */Jpeg_set_defaults (&cinfo);   /* Now the can set any Non-default parameters your wish to. * Here we just illustrate the use of quality (quantization table) Scaling: */jpeg_set_quality (&cinfo, quality, TRU  E/* Limit to BASELINE-JPEG values */);   /* Step 4:start Compressor */* TRUE ensures that we'll write a complete interchange-jpeg file.   * Pass TRUE unless you're very sure of what ' re doing. */jpeg_start_compress (& cinfo, TRUE); /* Step 5:while (scan lines remain to be written) */* jpeg_write_scanlines (...);  */* Here we use the library's state variable cinfo.next_scanline as the "loop counter, so" we don't have a to keep   Track ourselves. * To keep things simple, we pass one scanline per call;   Can pass * More if you wish, though.  */row_stride = imagerowsize; while (Cinfo.next_scanline < cinfo.image_height) {/* Jpeg_write_scanlines expects an array of pointers to Scanline S. * Here the array was only one element long, but you could pass * more than one scanline at a time if that's more C    Onvenient.   */row_pointer[0] = &image_buffer[cinfo.next_scanline * Row_stride];   Row_pointer[0] = &image_buffer[image_buffer_len-(cinfo.next_scanline + 1) * Row_stride];  (void) Jpeg_write_scanlines (&cinfo, Row_pointer, 1);  }/* Step 6:finish compression */jpeg_finish_compress (&cinfo); /* After finish_compress, we can close the output fIle.    */fclose (outfile); /* Step 7:release JPEG Compression Object */* This is an important step since it'll release a good deal of memory. */jpeg_destroy_compress (&cinfo); }//Release DIB array delete []dibbuffer; return 0;}

PS: Recently 1.5 in a busy project, has no time to update the blog, but also did not answer the questions of netizens, very sorry. Most of the problems are Baidu can be dealt with, can only say sorry. Screenshot saved as JPG is actually a small feature I used in the project, because it doesn't involve anything commercial, Just post it and share it. In the future, I will break down some of the features in the project into reusable code that you can exchange.

BMP and JPEG

Large-Scale Price Reduction
  • 59% Max. and 23% Avg.
  • Price Reduction for Core Products
  • Price Reduction in Multiple Regions
undefined. /
Connect with us on Discord
  • Secure, anonymous group chat without disturbance
  • Stay updated on campaigns, new products, and more
  • Support for all your questions
undefined. /
Free Tier
  • Start free from ECS to Big Data
  • Get Started in 3 Simple Steps
  • Try ECS t5 1C1G
undefined. /

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.