1、读取jpeg文件
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <jpeglib.h>
#include "opencv2/opencv.hpp"
int readJpeg(const char* filename, cv::Mat& pData)
{
FILE* infile;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "Can't open %s\n", filename);
return 0;
}
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
int width = cinfo.output_width;
int height = cinfo.output_height;
int channels = cinfo.output_components;
int channels = cinfo.jpeg_color_space;
pData = cv::Mat(height, width, CV_8UC3);
int row_stride = width * channels;
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
for (int i = 0; i < height; i++) {
jpeg_read_scanlines(&cinfo, buffer, 1);
for (int j = 0; j < width; j++) {
pData.at<cv::Vec3b>(i, j)[0] = buffer[0][j * channels + 2];
pData.at<cv::Vec3b>(i, j)[1] = buffer[0][j * channels + 1];
pData.at<cv::Vec3b>(i, j)[2] = buffer[0][j * channels + 0];
}
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 0;
}
2、写入JPEG文件
long writeJpeg(const char* ofilename, cv::Mat& pData)
{
struct my_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
typedef struct my_error_mgr* my_error_ptr;
auto my_error_exit = [](j_common_ptr cinfo){
my_error_ptr myerr = (my_error_ptr)cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
};
FILE* outfile;
if ((outfile = fopen(ofilename, "wb")) == NULL) {
fprintf(stderr, "Can't open %s\n", ofilename);
return 0;
}
struct jpeg_compress_struct cinfo;
struct my_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_compress(&cinfo);
fclose(outfile);
return 0;
}
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = pData.cols;
cinfo.image_height = pData.rows;
cv::Mat d_pData;
rgb2cmyk(pData, d_pData);
cinfo.input_components = 4;
cinfo.in_color_space = JCS_CMYK;
jpeg_set_defaults(&cinfo);
jpeg_start_compress(&cinfo, TRUE);
int row_stride = d_pData.cols * cinfo.input_components;
JSAMPROW row_pointer[1];
while (cinfo.next_scanline < cinfo.image_height) {
JSAMPROW row_pointer[1];
row_pointer[0] = &d_pData.data[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(outfile);
return 0;
}