c++修改jpg图像的dpi

Posted BHY_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++修改jpg图像的dpi相关的知识,希望对你有一定的参考价值。

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;

以上是关于c++修改jpg图像的dpi的主要内容,如果未能解决你的问题,请参考以下文章

如何在飞镖颤动中转换图像 dpi(每英寸点数)?

将画布作为 jpg 文件保存到服务器时如何增加 DPI?

python pil 怎么设定图片的dpi

安卓系统,5.5寸手机屏幕最合适的DPI是多少?

WPF中DPI的问题

使用 OpenCV(C++)读取文件夹中的任何 .jpg 图像 [关闭]