问题描述
我正在尝试根据EXIF元数据中存在的“方向”参数,使用libjpeg v9在C ++中旋转JPEG图像。我可以获取“方向”参数,并在此基础上将图像旋转到另一个文件中,以便旋转后的图像对应于“方向”值1。
请参阅我从“ jpegtran.c”文件中获取的代码,并且可以正常工作(不存在读取EXIF元数据代码):
#include <iostream>
#include <jpeglib.h>
#include <jerror.h>
#include "transupp.h"
void setTransformation(jpeg_transform_info *transformObj,JXFORM_CODE transformation){
transformObj->perfect = FALSE;
transformObj->trim = FALSE;
transformObj->force_grayscale = FALSE;
transformObj->crop = FALSE;
transformObj->transform = transformation;
}
void releaseRes(j_decompress_ptr srcPtr,j_compress_ptr destPtr){
jpeg_finish_compress(destPtr);
jpeg_destroy_compress(destPtr);
(void) jpeg_finish_decompress(srcPtr);
jpeg_destroy_decompress(srcPtr);
}
void rotateImage(const char *inputFilename,const char *outputFilename,JXFORM_CODE transformVal){
FILE *inputFile = fopen(inputFilename,"r");
if(inputFile==NULL){
std::cerr<<"ERROR: cannot open input file\n";
return;
}
struct jpeg_decompress_struct srcObj;
struct jpeg_error_mgr srcErrMgr;
struct jpeg_compress_struct destObj;
struct jpeg_error_mgr destErrMgr;
jvirt_barray_ptr *srcCoefArr;
jvirt_barray_ptr *destCoefArr;
//transformation object
jpeg_transform_info transformObj;
//set error handler
srcObj.err = jpeg_std_error(&srcErrMgr);
jpeg_create_decompress(&srcObj);
destObj.err = jpeg_std_error(&destErrMgr);
jpeg_create_compress(&destObj);
//set the transformation properties
setTransformation(&transformObj,transformVal);
jpeg_stdio_src(&srcObj,inputFile);
JCOPY_OPTION copyOpt = JCOPYOPT_DEFAULT;
jcopy_markers_setup(&srcObj,copyOpt);
(void) jpeg_read_header(&srcObj,TRUE);
if(!jtransform_request_workspace(&srcObj,&transformObj)){
std::cerr<<"Transformation is not perfect\n";
return;
}
srcCoefArr = jpeg_read_coefficients(&srcObj);
jpeg_copy_critical_parameters(&srcObj,&destObj);
destCoefArr = jtransform_adjust_parameters(&srcObj,&destObj,srcCoefArr,&transformObj);
FILE *outputFile = fopen(outputFilename,"wb");
if(outputFile==NULL){
std::cerr<<"ERROR: cannot open output file\n";
fclose(inputFile);
releaseRes(&srcObj,&destObj);
return;
}
jpeg_stdio_dest(&destObj,outputFile);
jpeg_write_coefficients(&destObj,destCoefArr);
jcopy_markers_execute(&srcObj,copyOpt);
jtransform_execute_transformation(&srcObj,&transformObj);
releaseRes(&srcObj,&destObj);
//close files
fclose(inputFile);
fclose(outputFile);
}
但是,我不想将旋转后的图像存储到另一个文件中,而是想就位旋转到缓冲区中或使用临时缓冲区,但不像上面的代码那样进行压缩。
下面是将解压缩后的数据放入缓冲区的代码:
void rotateImage(const char *filename){
FILE *file = fopen(filename,"r");
if(!file){
std::cerr<<"Error in reading file\n";
return;
}
struct jpeg_decompress_struct info;
struct jpeg_error_mgr jerr;
info.err = jpeg_std_error(&jerr);
jpeg_CreateDecompress(&info,JPEG_LIB_VERSION,(size_t) sizeof(struct jpeg_decompress_struct));
jpeg_stdio_src(&info,file);
(void) jpeg_read_header(&info,TRUE);
jpeg_start_decompress(&info);
uint32_t channels = 3;
uint32_t rowStride = info.output_width * channels;
uint64_t dataSize = rowStride * info.output_height;
unsigned char *buffer = new unsigned char[dataSize];
unsigned char *rowData[1];
while(info.output_scanline < info.output_height){
//initial value of output_Scanline state var is 0
rowData[0] = buffer + info.output_scanline * rowStride;
jpeg_read_scanlines(&info,rowData,1);
}
/*Now,i want to rotate this buffer (or with other temp buffer without compression as in
first code) as per "orientation",either 90,180,270*/
/* here */
jpeg_finish_decompress(&info);
jpeg_destroy_decompress(&info);
fclose(file);
delete buffer;
}
尽管如此,我还是尝试使用临时缓冲区(类似于非正方形矩阵的矩阵旋转)和以下90度代码来旋转缓冲区:
//90 degree clockwise
unsigned char *tmpBuf = new unsigned char[dataSize];
int row = info.output_height;
int col = info.output_width;
for(int i=0; i<row; i+=1){
for(int j=0;j<col; j+=1){
//copied 3 bytes as each pixed takes 3 bytes for RGB
memcpy(tmpBuf + (j*row + row-i-1)*3,buffer + (i*col + j)*3,3);
}
}
但是,我认为旋转JPEG的方法不正确,因为应用程序不接受旋转的数据,我正在将该数据发送到(FYI,我按照应用程序对它的“方向”进行旋转)。这使我相信这不是旋转JPEG图像的正确方法。与第一种方法一样,我要向其发送数据的应用程序首先接受压缩数据,然后再次将其解压缩为缓冲区。但是,我认为这不是更好的方法。
因此,我需要您的帮助。请让我知道实现它所需的步骤。任何代码示例或教程也将有所帮助。
谢谢
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)