This article only introduces the relevant content of JPEG compression. At the beginning, I tried to save time by using the features provided by Microsoft's GDI plus. It is very convenient to get the jpg image encoding first, create a bitmap object based on the bitmap data of the image, and save the image as JPG. However, I still have a lot of trust in GDI +, and I always feel unreliable (for no reason). Once our system is installed, it will run for a long time. I am worried that after a long running period of time, GDI + will have problems, the results also confirmed my concerns. We actually used one of the 10 systems. After three to five days of continuous operation, the GDI + collapsed, so I decided to use the JPEG g JPEG library. You can download the libjpeg source code from www.ijg.org. The ijg JPEG library is a JPEG compression library, which is provided to software developers in the form of source code, of course, there are also compiled library files in the software package. Here we only use libjpeg. lib (the name may also be libjpeg. la), jconfig. h, jmorecfg. h, using Lib. h. I will introduce how to embed image compression capabilities in my own program.
1. Build a compilation environment
The so-called establishment of the compilation environment is actually very simple, it is to copy the four files mentioned above to your project folder, put libjpeg. add lib to your project, and then add # include "Unzip Lib. H ", please note that libjpeg. lib is developed in C language. If it is used in your c ++ program, you need to use extern "C", as shown below:
// Testlibjpeg. cpp: defines the entry point for the console application.
//
# Include "stdafx. H"
# Include "memory. H"
Extern "C "{
# Include "cmdlib. H"
}
Ii. Compression steps
1. Request and initialize the JPEG compression object, and specify the error Processor
Struct cmd_compress_struct JCs;
// Declare the error processor and assign it to the JCS. Err domain
Struct performance_error_mgr JEM;
JCs. Err = maid (& Jem );
Pai_create_compress (& JCs );
2. Specify the target file for storing the compressed image. Note that the target file should be opened in binary mode.
F = fopen ("03.jpg"," WB ");
If (F = NULL)
{
Delete [] data;
Delete [] pdataconv;
Return 0;
}
Pai_stdio_dest (& JCs, F );
3. Set the compression parameters. The main parameters include the image width, height, and number of color channels (1: index image, 3: others). The color space (jcs_grayscale indicates the grayscale image, jcs_rgb indicates color image), compression quality, etc., as follows:
JCs. image_width = nwidth; // the width and height of the graph, in pixels.
JCs. image_height = nheight;
JCs. input_components = 1; // here it is 1, indicating a grayscale image. If it is a color bitmap, It is 3
JCs. in_color_space = jcs_grayscale; // jcs_grayscale indicates the grayscale image, and jcs_rgb indicates the color image.
Pai_set_defaults (& JCs );
Pai_set_quality (& JCs, 80, true );
Note that the jpeg_set_defaults function must be called only after the four parameters of the image width, height, and color channel color space are set, because these four values are used for this function, after the jpeg_set_defaults function is called, The jpeglib library uses the default settings to compress the image. If you need to change the settings, such as the compression quality, after calling this function, you can call other setting functions, such as the __set_quality function. In fact, many parameters can be set during image compression, but most of them do not need to be set. You only need to call the jpeg_set_defaults function to set the value to the default value.
4. After the preparation is complete, compress can be performed. The compression process is very simple. Call pai_start_compress first, compress each row, or compress several rows, you can even compress the entire image once. After compression, remember to call the pai_finish_compress function, as shown below:
Pai_start_compress (& JCs, true );
Jsamprow row_pointer [1]; // a row of Bitmap
Int row_stride; // The number of bytes in each row
Row_stride = JCs. image_width; // if it is not an index chart, multiply it by 3 (the number of bytes per pixel)
// Compress each row
While (JCs. next_scanline <JCs. image_height ){
Row_pointer [0] = & pdataconv [JCs. next_scanline * row_stride];
Pai_write_scanlines (& JCs, row_pointer, 1 );
}
Pai_finish_compress (& JCs );
5. The final part is to release the resources applied during the compression process, which is mainly JPEG compression objects. In this example, I use local variables directly, therefore, you only need to call the pai_destroy_compress function as follows:
Pai_destroy_compress (& JCs );
Iii. Decompression steps
The decompression steps are very similar to the compression steps, but the decompression object is of the pai_decompress_struct type. The steps are as follows:
1. Declare and initialize the decompression object, and create an error message manager.
Struct performance_decompress_struct Cinfo;
Struct performance_error_mgr Jerr;
Cinfo. Err = maid (& Jerr );
Pai_create_decompress (& Cinfo );
2. Open a jpg image file and specify the source file as the decompressed object.
File * f = fopen (strsourcefilename, "rb ");
If (F = NULL)
{
Printf ("Open File error! \ N ");
Return;
}
//
Performance_stdio_src (& Cinfo, F );
3. Read Image Information
Pai_read_header (& Cinfo, true );
4. Apply for an image buffer zone based on image information
Data = new byte Cinfo. image_width * Cinfo. image_height * Cinfo. num_components];
5. Start Decompression
Pai_start_decompress (& Cinfo );
Jsamprow row_pointer [1];
While (Cinfo. output_scanline <Cinfo. output_height)
{
Row_pointer [0] = & Data [(Cinfo. output_height-Cinfo. output_scanline-1) * Cinfo. image_width * Cinfo. num_components];
Pai_read_scanlines (& Cinfo, row_pointer,
1 );
}
Pai_finish_decompress (& Cinfo );
6. release resources
Pai_destroy_decompress (& Cinfo );
Fclose (f );
Let's take a look at how to use ijg JPEG library to compress images. I hope it will be helpful to you. The sample code has implemented all the functions of image compression and decompression. The command format is: unzip testlibcmd.exe j | j24 | B source file name target file name ", where option J compresses the source file to JPG format without changing the color mode. The j24 option compresses the source file to 24 in JPG format, option B decompress the source file to BMP format. The instance does not provide file validity verification. If you want to introduce your own code, verify the file validity.
Convert BMP to JPEG program source code in Linux
/****************************************************************************
Name: bmp-to-jpeg. C
Function: convert BMP into JPEG program source code under Linux
Copyright: Sichuan Key Laboratory of signal and information processing, Southwest Jiaotong University
Author: Huang Wenhui
Date: January 26, 2010
Note: add "- ljpeg" (GCC - O mm bmp-to-jpeg. C - ljpeg) at compile time
*****************************************************************************/
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/videodev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/timeb.h>
#include <jpeglib.h>
#define JPEG_QUALITY 80
Int main ()
{
FILE *fd;
Int ret;
unsigned char *data;
long sizeImage;
sizeImage = 320*240*sizeof(unsigned char);
data = (unsigned char*)malloc(sizeImage);
fd = fopen("palm.bmp", "rb");
If (FD)
{
printf("ERROR1: Can not open the image.\n");
Free (data);
Return -1;
}
//Skip the BMP file header and read the palmprint image data directly
fseek(fd, 1078, SEEK_SET);
ret = fread(data, sizeof(unsigned char)*sizeImage, 1, fd);
If (RET = = 0)
{
if(ferror(fd))
{
printf("\nERROR2: Can not read the pixel data.\n");
Free (data);
Fclose (FD);
Return -1;
}
}
char *filename = "palm2.jpg";
int width = 320;
int height = 240;
int depth = 1;
//unsigned char *bits = "jsdgjksdjkgjks51sd536gsgjmskjgksjgss231h1b2s123z";
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 */
cinfo.err = jpeg_std_error(&jerr);
/* Now we can initialize the JPEG compression object. */
jpeg_create_compress(&cinfo);
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
Return -1;
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = width; /* image width and height, in pixels */
cinfo.image_height = height;
cinfo.input_components = depth; /* # of color components per pixel */
cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
/* Now you can set any non-default parameters you wish to.
* Here we just illustrate the use of quality (quantization table) scaling:
* /
jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE ); /* limit to baseline-JPEG values */
jpeg_start_compress(&cinfo, TRUE);
row_stride = width; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & data[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
Free (data);
Fclose (FD);
fclose(outfile);
Return 0;
}
Link: http://blog.chinaunix.net/uid-26544753-id-3049279.html