照片处理小工具三合一设计到实现(二)

后来考虑到平时不管是手机还是相机,照片尺寸都比较大,保存的文件也都很大,而我们实际上并不需要那么大的文件,于是考虑可以批量修改照片尺寸,虽然市面上各种图像处理软件都能够实现该功能,但是他们很多都会导致一个问题,EXIF信息丢失!并且加入了被软件处理过的信息!这必然是我不想看到的,于是自己写了一个,采用了多线程,速度也比一般的软件快。

软件界面是这样的,改变尺寸同时保留EXIF信息。


软件基本使用正常,因为使用了GDAL库,所以对于输入图像的尺寸也没有限制,本以为这样这个小软件就结束了,结果发现一个问题,GDAL直接处理GIF文件的时候会有问题,具体表现就是如果读取GIF文件,会把彩色读取成黑白的,如果直接修改GIF的尺寸,处理之后的图片颜色信息丢失了!!

调试发现,原来读取GIF的时候,GDAL会把通道数读取成1,在网上搜索无果之后,后续考虑对GIF文件单独处理,经过抉择最终采用了CxImage类。


关键代码为:

int CResizePictures::ResizePics(const char* pInputPath, const char* pSavePath, const int& nProcessIndex)
{
	CGdalUser gu;
	if (!gu.Initialize(pInputPath))
	{
		return -1;
	}

	//获取exif信息
	ExifPathsTags pathsTags;
	ExifImageFile               inImageFile;
	ExifStatus                  status(EXIF_INVALID_FORMAT_ERROR);
	ExifStatus					openStatus(EXIF_INVALID_FORMAT_ERROR);
	std::string dstExtension = CStdStr::ToUpperLower(CStdStr::GetSuffixOfFile(pInputPath));
	bool bExif = 0 == strcmp(dstExtension.c_str(), ".jpg") || 0 == strcmp(dstExtension.c_str(), ".jpeg");
	if (bExif)
	{
		openStatus = inImageFile.open(pInputPath, "r+");
		if (openStatus != EXIF_OK)	//不能用w打开照片,打开后会重新创建一张照片并将原来的照片覆盖掉
		{
			inImageFile.close();
		}
		status = inImageFile.getAllTags(0xFFE1, "Exif", pathsTags) ;
		if (status != EXIF_OK)
		{
			inImageFile.close();
		}
	}

	double dPropWH = (double)gu.m_nImgWidth / gu.m_nImgHeight;

	int nNewWidth = g_nImgWidth;
	int nNewHeight = g_nImgHeight;

	double dPropScale = 1.0;
	if(g_bKeepScale)
	{
		//如果保持比例才计算
		if (gu.m_nImgWidth < gu.m_nImgHeight)
		{
			dPropScale = (double)nNewWidth / gu.m_nImgWidth;
			nNewHeight = int(gu.m_nImgHeight * dPropScale);

			if (nNewHeight <= 0)
			{
				nNewHeight = 1;
			}
		}
		else
		{
			dPropScale = (double)nNewHeight / gu.m_nImgHeight;
			nNewWidth = int(gu.m_nImgWidth * dPropScale);
			if (nNewWidth <= 0)
			{
				nNewWidth = 1;
			}
		}
	}

	bool bGif = 0 == strcmp(dstExtension.c_str(), ".gif");
	unsigned char* pData = nullptr;
	if (bGif)
	{
		//Gif文件需要单独处理
		if (CxImageUser::ResizeGif(CStdStr::s2ws(pInputPath), CStdStr::s2ws(pSavePath), nNewWidth, nNewHeight))
		{
			g_vLog[nProcessIndex] = (std::string(pInputPath) + "->" + std::string(pSavePath) + '\n');
		}
		else
		{
			//保存失败
			g_vLog[nProcessIndex] = ("Resize" +  std::string(pInputPath) + " Failed!" + '\n');

			return -1;
		}
	}
	else if (gu.readImageGDAL(&pData, nNewWidth, nNewHeight, gu.m_nBandNum, pInputPath))
	{
		//保存结果
		if (gu.WriteImageGDAL(pSavePath, pData, nNewWidth, nNewHeight, gu.m_nBandNum))
		{
			if (status == EXIF_OK)
			{
				//增加exif信息
				SetPicExifInfo(pSavePath, pathsTags);
			}
			g_vLog[nProcessIndex] = (std::string(pInputPath) + "->" + std::string(pSavePath) + '\n');
		}
		else
		{
			//保存失败
			g_vLog[nProcessIndex] = ("Resize" +  std::string(pInputPath) + " Failed!" + '\n');

			return -1;
		}

		delete[] pData;
		pData = nullptr;
	}

	return 0;
}

当然,这个小软件最终被合并到三合一那个软件中了。

如图:


对于GIF图像也能够实现缩放,并且保留动画效果,不过这个功能比较耗时,因为要对gif文件的每一帧都进行缩放。

于是尺寸修改功能告一段落。

(未完待续)

猜你喜欢

转载自blog.csdn.net/autumoonchina/article/details/78548230