像素比对 - 类似找茬游戏

 
//
/*
 当前获得当前文件夹下同等大小图片,比对像素,如果不一样就为空,一样就保留。类似找茬游戏
*/

#include "pch.h"
#include <iostream>
#include<atlimage.h>
#include<vector>
 
#include <direct.h>

#pragma warning (disable : 4996)
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
#include<io.h>
#include<stdio.h>
using namespace std;
using namespace Gdiplus;

//隐藏控制台,不能使用system("pause")
//#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	UINT num = 0;
	UINT size = 0;

	ImageCodecInfo* pImageCodecInfo = NULL;

	GetImageEncodersSize(&num, &size);
	if (size == 0)
	{
		return -1;
	}
	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
	if (pImageCodecInfo == NULL)
	{
		return -1;
	}

	GetImageEncoders(num, size, pImageCodecInfo);

	for (UINT j = 0; j < num; ++j)
	{
		if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;
		}
	}

	free(pImageCodecInfo);
	return -1;
}  
void getAllFiles(string path, vector<string>& files)
{
	char szFileFullPath[MAX_PATH], szProcessName[MAX_PATH];
	::GetModuleFileNameA(NULL, szFileFullPath, MAX_PATH);//获取文件路径
	int length = ::strlen(szFileFullPath);
	for (int i = length - 1; i >= 0; i--)//从路径后面开始找\,即倒着找右斜杠
	{
		if (szFileFullPath[i] == '\\')//找到第一个\,就可以马上获取进程名称了
		{
			i++;
			for (int j = 0; i <= length; j++)//结束符\0不能少,即i=length
			{
				szProcessName[j] = szFileFullPath[i++];
			}
			break;
		}
	} 

	//文件句柄 
	long  hFile = 0;
	//文件信息 
	struct _finddata_t fileinfo; //很少用的文件信息读取结构
	string p; //string类很有意思的一个赋值函数:assign(),有很多重载版本
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
		do
		{
			if ((fileinfo.attrib & _A_SUBDIR)) //判断是否为文件夹
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
				{
					files.push_back(p.assign(path).append("/").append(fileinfo.name));//保存文件夹名字
					getAllFiles(p.assign(path).append("/").append(fileinfo.name), files);//递归当前文件夹
				}
			}
			else  //文件处理
			{
				if (strcmp(fileinfo.name, szProcessName)==0)
					continue;
				files.push_back(p.assign(path).append("/").append(fileinfo.name));//文件名
			}
		} while (_findnext(hFile, &fileinfo) == 0); //寻找下一个,成功返回0,否则-1
		_findclose(hFile);
	}
}
wstring string2wstring(string str)
{
	wstring result;
	//获取缓冲区大小,并申请空间,缓冲区大小按字符计算  
	int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
	TCHAR* buffer = new TCHAR[len + 1];
	//多字节编码转换成宽字节编码  
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
	buffer[len] = '\0';             //添加字符串结尾  
	//删除缓冲区并返回值  
	result.append(buffer);
	delete[] buffer;
	return result;
}
//将wstring转换成string  
string wstring2string(wstring wstr)
{
	string result;
	//获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的  
	int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
	char* buffer = new char[len + 1];
	//宽字节编码转换成多字节编码  
	WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
	buffer[len] = '\0';
	//删除缓冲区并返回值  
	result.append(buffer);
	delete[] buffer;
	return result;
}
int main(int argc, char* argv[])
{
	GdiplusStartupInput gdiplusstartupinput;
	ULONG_PTR gdiplustoken;
	GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
	
	vector<string>_vecPath;

	char filepath[MAX_PATH] = ".\\";	 
	getcwd(filepath, sizeof(filepath));
 
	string DATA_DIR(filepath);

	getAllFiles(DATA_DIR, _vecPath);//所有文件与文件夹的路径都输出

	if (_vecPath.size() == 0)
	{
		printf("无任何图片\n");
		system("pause");
		return 0;
	}	 
	
	vector<Bitmap*>_vecBitmap;
	for (size_t _i = 0; _i < _vecPath.size(); _i++)
	{
		printf("文件:%s\n", _vecPath[_i].c_str());
		_vecBitmap.push_back(new Bitmap(string2wstring(_vecPath[_i]).c_str()));
	}

	UINT height = _vecBitmap[0]->GetHeight();
	UINT width = _vecBitmap[0]->GetWidth();

	Bitmap* SameImg = _vecBitmap[0];//new Bitmap(width, height);
	 
	cout << "width " << width << ", height " << height << endl;

	vector<Color>_vecColor;
	Gdiplus::Color color;
	Gdiplus::Color colorAlpha(0,0, 0, 0);// 透明
	//Gdiplus::Color colorBlack( 0, 0, 0);//黑色
	vector<SIZE>_vecSize;
	int ntime1 = GetTickCount();
	for (UINT y = 0; y < height; y++)
		for (UINT x = 0; x < width; x++)
		{

			Gdiplus::Color colorMaster;
			_vecBitmap[0]->GetPixel(x, y, &colorMaster);

			for (size_t _i = 1; _i < _vecBitmap.size(); _i++)
			{
				_vecBitmap[_i]->GetPixel(x, y, &color);
				if (color.GetValue() == colorMaster.GetValue())
					;//bmpNew->SetPixel(x, y, colorMaster);
				else
				{
					/*SIZE _t;
					_t.cx = x;
					_t.cy = y;
					_vecSize.push_back(_t);*/
				 	SameImg->SetPixel(x, y, colorAlpha);
				 
				}
			}
		}
	
		/*for (size_t _i = 0; _i < _vecSize.size(); _i++)
		{
			bmpNew->SetPixel(_vecSize[_i].cx, _vecSize[_i].cy, colorBlack);
		}*/

	CLSID BmpClsid;
	GetEncoderClsid(_T("image/png"), &BmpClsid);
	std::wstring m_strSaveBmp = string2wstring(filepath) + _T("\\SameImg.png");
	SameImg->Save(m_strSaveBmp.c_str(), &BmpClsid); 

 	delete SameImg;
	GdiplusShutdown(gdiplustoken);

	int ntime2 = GetTickCount();
	printf("时间:%d ms\n", ntime2 - ntime1);
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值