opencv处理保存后的图像,会改变其原来的dpi数值
先调用读取jpg图片的dpi函数,然后opencv保存后,再写入原先的dpi值
下面是修改jpg图片的dpi函数
bool SetResolution(const char* path, int iResolution)
{
FILE * file = fopen(path,"rb+");// - 打开图片文件
if (!file)return false;
int len = _filelength(_fileno(file));// - 获取文件大小
char* buf = new char[len];
fread(buf, sizeof(char), len, file);// - 将图片数据读入缓存
char * pResolution = (char*)&iResolution;// - iResolution为要设置的分辨率的数值,如72dpi
// - 设置JPG图片的分辨率
buf[0x0D] = 1;// - 设置使用图片密度单位
// - 水平密度,水平分辨率
buf[0x0E] = pResolution[1];
buf[0x0F] = pResolution[0];
// - 垂直密度,垂直分辨率
buf[0x10] = pResolution[1];
buf[0x11] = pResolution[0];
// - 将文件指针移动回到文件开头
fseek(file, 0, SEEK_SET);
// - 将数据写入文件,覆盖原始的数据,让修改生效
fwrite(buf, sizeof(char), len, file);
fclose(file);
return true;
}
下面是读取jpg图片的dpi函数
PdfJpeg.h
#pragma once
#include <string.h>
#include <stdio.h>
#pragma warning(disable: 4244)
class PdfJpeg
{
public:
PdfJpeg(void);
~PdfJpeg(void);
PdfJpeg(char *filename):
weidth(0),height(0),buffer(NULL),length(0),file(filename?filename:NULL),name(NULL){}
private:
//jpeg宽度
int weidth;
//jpeg高度
int height;
//jpeg数据
unsigned char *buffer;
//jpeg数据长度
long length;
//jpeg文件名和路径
char *file;
//jpeg文件名
char *name;
PdfJpeg& operator=(const PdfJpeg &j);
//获取jpeg图片尺寸
int GetSize(unsigned char * buffer,long length);
float inline JepgSize(int x)
{
return x!=2?1:2.56;
}
//垂直像素点
float hpx;
//水平像素点
float wpx;
public:
//读取jpeg文件,失败返回-1,成功返回1
int ReadImage();
int inline GetWidth() const
{
return weidth;
}
int inline GetHeight() const
{
return height;
}
unsigned char inline *GetData() const
{
return buffer;
}
long inline GetDataLength() const
{
return length;
}
char * GetFileName() const
{
return name;
}
float inline GetHDpi()
{
return hpx;
}
float inline GetWDpi()
{
return wpx;
}
float inline GetCompressionRatio()
{
return 1.0 * length / (3 * weidth * height) ;
}
};
PdfJpeg.cpp
#include "PdfJpeg.h"
PdfJpeg::PdfJpeg(void):weidth(0),height(0),buffer(NULL),length(0),file(NULL),name(NULL)
{
}
PdfJpeg::~PdfJpeg(void)
{
delete[]buffer;
}
int PdfJpeg::ReadImage()
{
if(file==NULL)
return -1;
if(strrchr(file,'.'))
name=strrchr(file,'.')+1;
if(!strcmp(name,".jpg")||!strcmp(name,".JPG"))
{
printf("%s文件,未被支持格式 \n" ,file);
return -1;
}
//获取文件名
if(strrchr(file,'\\'))
name=strrchr(file,'\\')+1;
else
name=file;
//读取jpeg数据
FILE *filejpeg;
errno_t err=fopen_s(&filejpeg,file,"rb");
if(err)
{
printf("读取%s文件,产生错误号:%i \n" ,file,err);
return -1;
}
fseek(filejpeg,0,SEEK_END);
length=ftell(filejpeg);
buffer=new unsigned char[length];
fseek(filejpeg,0,SEEK_SET);
fread(buffer,length,1,filejpeg);
fclose(filejpeg);
return GetSize(buffer,length);
}
int PdfJpeg::GetSize(unsigned char * buffer,long length)
{
if(!buffer)
return -1;
unsigned char * temp=buffer+length,*temp1=buffer;
unsigned char ff,type=0xff;
int m_ret=-1,m_pos=0,m_hpx=0,m_wpx=0,uits=0;
if(*buffer++!=0xff||*buffer++!=0xd8)
{
printf("此非jepg图片\n");
return -1;
}
while(temp>buffer&&type!=0xDA)
{
do
{
ff=*buffer++;
} while (ff!=0xff);
do
{
type=*buffer++;
} while (type==0xff);
switch(type)
{
case 0x00:
case 0x01:
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
break;
case 0xC0://SOF0段
temp1=buffer;
m_pos=(*buffer++)<<8;
m_pos+=*buffer++;
buffer++; //舍弃精度值
height=(*buffer++)<<8;
height+=*buffer++;
weidth=(*buffer++)<<8;
weidth+=*buffer;
m_ret++;
break;
case 0xE0: //APP0段
temp1=buffer;
m_pos=(*buffer++)<<8;
m_pos+=*buffer++;
buffer=buffer+7; //丢弃APP0标记(5bytes)以及主版本号(1bytes)及次版本号(1bytes)
uits=*buffer++; //0: 无单位,units=1:点数/英寸,units=2:点数/厘米
m_wpx=(*buffer++)<<8;
m_wpx+=*buffer++;
m_hpx=(*buffer++)<<8;
m_hpx+=*buffer++;
hpx=m_hpx*JepgSize(uits);
wpx=m_wpx*JepgSize(uits);
m_ret++;
break;
default:
temp1=buffer;
m_pos=(*buffer++)<<8;
m_pos+=*buffer++;
break;
}
buffer=temp1+m_pos;
}
return m_ret;
}