对libjpeg库进行再包装

来源:互联网 发布:淘宝职业差评师团队 编辑:程序博客网 时间:2024/06/03 13:40

说句老实话,直接使用libjpeg库进行图像处理的编程,使用起来不是很顺手。所以,我打算对libjpeg库进行一些小小的扩展或者包装吧,其实,进行图像处理,无非需要对图片进行读取、处理、写入而已。而处理通常就是使用特定的算法来对图像的像素数据进行操作,最后保存为文件。

废话少说,看看代码吧:

-------------------------------------------------QhLibJpeg.h---------------------------------------------------

#ifndef __QH_LIBJPEG_H__#define __QH_LIBJPEG_H__#include <stdio.h>#include <setjmp.h>#include "jpeglib.h"typedef struct tagJpegColor{unsigned char R;unsigned char G;unsigned char B;}JpegColor;typedef struct tagJpegFile{unsigned char* Pixels;unsigned int Width;unsigned int Height;unsigned int Stride;}JpegFile;struct QhLibJpeg_error_mgr {  struct jpeg_error_mgr pub;/* "public" fields */  jmp_buf setjmp_buffer;/* for return to caller */};typedef struct QhLibJpeg_error_mgr * my_error_ptr;int ReadJpegFile(char* fileName, JpegFile* jpegFile);int WriteJpegFile(const JpegFile* jpegFile,char* fileName, int quality);JpegColor GetPixelColor(const JpegFile* jpegFile,unsigned int row,unsigned int col);void SetPixelColor(JpegFile* jpegFile,unsigned int row,unsigned int col,JpegColor clr);void SetRegionColor(JpegFile* jpegFile,unsigned int x,unsigned int y,unsigned int width,unsigned int height,JpegColor clr);void DestroyJpegFile(JpegFile* jpeg);#endif

---------------------------------------------QhLibJpeg.c-----------------------------------------------------

#include "QhLibJpeg.h"void QhLibJpeg_error_exit (j_common_ptr cinfo){  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */  my_error_ptr myerr = (my_error_ptr) cinfo->err;  /* Always display the message. */  /* We could postpone this until after returning, if we chose. */  (*cinfo->err->output_message) (cinfo);  /* Return control to the setjmp point */  longjmp(myerr->setjmp_buffer, 1);}int ReadJpegFile(char* fileName, JpegFile* jpegFile){struct jpeg_decompress_struct cinfo;struct QhLibJpeg_error_mgr jerr;FILE* infile;//JSAMPARRAY buffer;JSAMPROW row_pointer[1];int row_stride;int counter = 0;int i = 0;if((infile=fopen(fileName,"rb"))==NULL){fprintf(stderr,"can't open %s to read.\n",fileName);return 0;}cinfo.err = jpeg_std_error(&jerr.pub);jerr.pub.error_exit = QhLibJpeg_error_exit;if(setjmp(jerr.setjmp_buffer)){jpeg_destroy_decompress(&cinfo);fclose(infile);return 0;}jpeg_create_decompress(&cinfo);jpeg_stdio_src(&cinfo,infile);jpeg_read_header(&cinfo,TRUE);jpeg_start_decompress(&cinfo);row_stride = cinfo.output_width * cinfo.output_components;//buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,row_stride,1);row_pointer[0] = (unsigned char*)malloc(cinfo.output_width*cinfo.num_components);jpegFile->Width = cinfo.output_width;jpegFile->Height = cinfo.output_height;jpegFile->Stride = row_stride;jpegFile->Pixels = (unsigned char*)malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components*sizeof(char));while(cinfo.output_scanline < cinfo.output_height){jpeg_read_scanlines(&cinfo,row_pointer,1);//memcpy(jpegFile->Pixels+counter,buffer[0],row_stride);//counter += row_stride;for(i=0;i<cinfo.image_width*cinfo.num_components;i++)jpegFile->Pixels[counter++] = row_pointer[0][i];}jpeg_finish_decompress(&cinfo);jpeg_destroy_decompress(&cinfo);fclose(infile);free(row_pointer[0]);return 1;}int WriteJpegFile(const JpegFile* jpegFile,char* fileName, int quality){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 counter = 0;cinfo.err = jpeg_std_error(&jerr);jpeg_create_compress(&cinfo);if ((outfile = fopen(fileName, "wb")) == NULL) {    fprintf(stderr, "can't open %s to write.\n", fileName);    exit(1);  }  jpeg_stdio_dest(&cinfo, outfile);  cinfo.image_width = jpegFile->Width; /* image width and height, in pixels */  cinfo.image_height = jpegFile->Height;  cinfo.input_components = 3;/* # of color components per pixel */  cinfo.in_color_space = JCS_RGB; /* colorspace of input image */jpeg_set_defaults(&cinfo);jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);jpeg_start_compress(&cinfo, TRUE);  while (cinfo.next_scanline < cinfo.image_height) {    /* jpeg_write_scanlines expects an array of pointers to scanlines.     * Here the array is only one element long, but you could pass     * more than one scanline at a time if that's more convenient.     */    row_pointer[0] = & jpegFile->Pixels[cinfo.next_scanline * cinfo.image_width * cinfo.input_components];//row_pointer[0] = jpegFile->Pixels+counter;    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);//counter += jpegFile->Stride;  }jpeg_finish_compress(&cinfo);fclose(outfile);jpeg_destroy_compress(&cinfo);return 1;}JpegColor GetPixelColor(const JpegFile* jpegFile,unsigned int row,unsigned int col){JpegColor color;if( !(jpegFile->Height > row && row >= 0) ){fprintf(stderr,"row must be in 0 to %d.\r\n",jpegFile->Height-1);return color;}if( !( jpegFile->Width >col && col >= 0 ) ){fprintf(stderr,"col must be in 0 to %d.\r\n",jpegFile->Width-1);return color;}color.R = (unsigned char)*(jpegFile->Pixels+jpegFile->Stride*row+col*3);color.G = (unsigned char)*(jpegFile->Pixels+jpegFile->Stride*row+col*3+1);color.B = (unsigned char)*(jpegFile->Pixels+jpegFile->Stride*row+col*3+2);return color;}void SetPixelColor(JpegFile* jpegFile,unsigned int row,unsigned int col,JpegColor clr){if( !(jpegFile->Height > row && row >= 0) ){fprintf(stderr,"row must be in 0 to %d.\r\n",jpegFile->Height-1);return;}if( !( jpegFile->Width >col && col >= 0 ) ){fprintf(stderr,"col must be in 0 to %d.\r\n",jpegFile->Width-1);return;}*(jpegFile->Pixels+jpegFile->Stride*row+col*3) = clr.R;*(jpegFile->Pixels+jpegFile->Stride*row+col*3+1) = clr.G;*(jpegFile->Pixels+jpegFile->Stride*row+col*3+2) = clr.B;}void SetRegionColor(JpegFile* jpegFile,unsigned int x,unsigned int y,unsigned int width,unsigned int height,JpegColor clr){int i = 0, j = 0;for(i=x;i<(x+width);i++){for(j=y;j<(y+height);j++){SetPixelColor(jpegFile,j,i,clr);}}}void DestroyJpegFile(JpegFile* jpegFile){free(jpegFile->Pixels);jpegFile->Pixels = 0;}

---------------------------------------------main.c------------------------------------------------

#include <stdio.h>#include <stdlib.h>#include "QhLibJpeg.h"#define MAX_PATH_LENGTH256int main(int argc, char *argv[]){char fileName[MAX_PATH_LENGTH];JpegFile jpeg;JpegColor clr;unsigned int row = 0;unsigned int col = 0;printf("Input the JPEG file Path: ");scanf("%s",fileName);if( !(ReadJpegFile(fileName,&jpeg)) ){fprintf(stderr,"read jpeg file error\r\n");return -1;}printf("Pixel get: ");scanf("%d,%d",&row,&col);clr = GetPixelColor(&jpeg,row,col);printf("%d,%d,%d\r\n",clr.R,clr.G,clr.B);printf("Pixel set: ");scanf("%d,%d,%d,%d,%d",&row,&col,&clr.R,&clr.G,&clr.B);SetPixelColor(&jpeg,row,col,clr);printf("Pixel get: ");scanf("%d,%d",&row,&col);clr = GetPixelColor(&jpeg,row,col);printf("%d,%d,%d\r\n",clr.R,clr.G,clr.B);printf("Region clr: ");scanf("%d,%d,%d,%d,%d",&row,&col,&clr.R,&clr.G,&clr.B);SetRegionColor(&jpeg,col,row,50,50,clr);printf("Pixel get: ");scanf("%d,%d",&row,&col);clr = GetPixelColor(&jpeg,row,col);printf("%d,%d,%d\r\n",clr.R,clr.G,clr.B);printf("Output the JPEG file Path: ");scanf("%s",fileName);WriteJpegFile(&jpeg,fileName,30);DestroyJpegFile(&jpeg);return 0;}

这样的话,以后不愁读取Jpeg图片麻烦了,呵呵~


原创粉丝点击