C+中的JPEG图像旋转+;使用libjpeg 我试图在LIJPEG V9中基于EXIF元数据中存在的“定位”参数在JC++中旋转JPEG图像。我能够得到“方向”参数,并在此基础上,我还能够将图像旋转到另一个文件中,使旋转后的图像对应于“方向”值1
请参阅我从“jpegtran.c”文件中获取的代码,该代码工作正常(读取EXIF元数据代码不存在):C+中的JPEG图像旋转+;使用libjpeg 我试图在LIJPEG V9中基于EXIF元数据中存在的“定位”参数在JC++中旋转JPEG图像。我能够得到“方向”参数,并在此基础上,我还能够将图像旋转到另一个文件中,使旋转后的图像对应于“方向”值1,c++,image-rotation,libjpeg,C++,Image Rotation,Libjpeg,请参阅我从“jpegtran.c”文件中获取的代码,该代码工作正常(读取EXIF元数据代码不存在): #包括 #包括 #包括 #包括“transupp.h” void setTransformation(jpeg_transform_info*transformObj、JXFORM_代码转换){ transformObj->perfect=FALSE; transformObj->trim=FALSE; transformObj->force_grayscale=FALSE; transform
#包括
#包括
#包括
#包括“transupp.h”
void setTransformation(jpeg_transform_info*transformObj、JXFORM_代码转换){
transformObj->perfect=FALSE;
transformObj->trim=FALSE;
transformObj->force_grayscale=FALSE;
transformObj->crop=FALSE;
transformObj->transform=转换;
}
无效释放器(j_解压缩\u ptr srcPtr,j_压缩\u ptr destPtr){
jpeg_完成_压缩(destPtr);
jpeg_销毁_压缩(destPtr);
(无效)jpeg_完成_解压缩(srcPtr);
jpeg_销毁_解压缩(srcPtr);
}
void rotateImage(常量字符*输入文件名,常量字符*输出文件名,JXFORM_代码转换值){
FILE*inputFile=fopen(inputFilename,“r”);
if(inputFile==NULL){
std::Cerr是否可以指定发送数据的应用程序所接受的数据格式?如果目标应用程序接受,则可以像您看起来那样旋转未压缩像素数据的像素矩阵。我还建议将旋转后的矩阵保存到磁盘(或在屏幕上显示)因此,您可以检查旋转是否正确。@PedroBoechat,谢谢您的回答。在中,旋转涉及使用DCT系数和其他步骤,我不理解。因此,我认为从这一点来看,我的矩阵旋转代码似乎不正确。不是吗?从第一个代码开始,我从解压缩数据压缩旋转图像。这然后解压旋转后的图像,应用程序接受其数据。因此,格式为正常原始RGB 24位。请指定要发送数据的应用程序接受的数据格式。如果目标应用程序接受,则可以像您看起来那样旋转未压缩像素数据的像素矩阵。我建议还建议将旋转矩阵保存到磁盘(或在屏幕上显示)因此,您可以检查旋转是否正确。@PedroBoechat,谢谢您的回答。在中,旋转涉及使用DCT系数和其他步骤,我不理解。因此,我认为从这一点来看,我的矩阵旋转代码似乎不正确。不是吗?从第一个代码开始,我从解压缩数据压缩旋转图像。这旋转后的图像被解压,其数据被应用程序接受。因此,格式为正常原始RGB 24位。
#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, &destObj, copyOpt);
jtransform_execute_transformation(&srcObj, &destObj, srcCoefArr, &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 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);
}
}