高仿大漠找字FindStr

高仿大漠找字FindStr

C++高仿大漠找字FindStr

字库就用大漠字库就可以了。

大家先来看看效果图:

砸门先制作一个这样的字库:

上面就是我定义的方字!当然了随你高兴写成什么字都可以。

但是最高不能超过256个字节

效果图如下:

看下调用方法

首先申请一个程序集变量:

TKdmsoft dm;//天空大漠

dm.SetPath(“d:\”);//设置操作的磁盘地址

dm.SetDict(“找字.txt”);//设置字库

int x=-1, y=-1;//申请两个返回的地址

//time_t t; time(&t);

//tm* m=localtime(&t);

//

//int sbb= m->tm_sec;

dm.FindStr(0, 1, 215, 113, "方方", "ff0000-050505", x, y);//调用方法

if (x>=0)

{

str.Format("%d", x);

SetDlgItemText(EDIT_x, str);

str.Format("%d", y);

SetDlgItemText(EDIT_y, str);

}

下面是找字类:

FindstrEx.h

#pragma once

struct MyDict

{

char* Dict; //要操作字体的点阵

char Neam[256] = {0}; //要操作的字符名称

int yxxs;//有效像数

int spxs;//竖排行数

};

struct MyDictwh

{

int w;//字体宽度

int h;//字体高度

};

class TKdmsoft

{

public:

TKdmsoft();

TKdmsoft(HWND hnd);

~TKdmsoft();

public:

int FindStr(int x1, int y1, int x2, int y2, const char* str, const char* color_format, int& X, int& Y);

long SetDict(char* file);

long SetPath(char* path);

long Sethwnd(HWND hwnd);

long CloseTk();//释放插件

long GetZtSize();//获取寻找的文字个数

private:

int GetDict(int dex, const char* str_a);//解析大漠字库

char* GetDictWh(const char* str, int& W, int& h, int& uto); //取回字符宽高

private:

char* strpath=NULL;//操作默认磁盘

MyDict* Dict=NULL;//字库文件

MyDictwh* dictwh; //当次字体大小

int DictSize = 0; //字库大小或有多少个字

HWND g_hwnd; //需要操作的窗口句柄

int ZTsize = 0; //字体大小

};

inline long TKdmsoft::CloseTk()

{

for (size_t i = 0; i < DictSize; i++)

{

delete[] Dict[i].Dict;

}

delete[] Dict;

delete[] strpath;

return 0;

}

long TKdmsoft::GetZtSize()//返回字体个数

{

if (ZTsize==0)

{

return 0;

}

return ZTsize;

}

// 天空插件

TKdmsoft::TKdmsoft(HWND hnd )

{

g_hwnd = hnd;

}

TKdmsoft::~TKdmsoft()

{

}

inline TKdmsoft::TKdmsoft()

{

}

long TKdmsoft::Sethwnd(HWND hwnd)

{

if (hwnd==0)

{

return -1;

}

g_hwnd = hwnd;

return 0;

}

//取两个十进制数的差,返回:十六进制文本

CString QCZ(int p1, int p2)

{

CString str;

str = IntToHex(abs(p1 - p2));

if (str.GetLength() == 2)

{

return str;

}

if (str.GetLength() == 1)

{

return "0" + str;

}

if (str.GetLength() == 0)

{

return "00";

}

return "";

}

//取色差

int QSC(CString str, int& c1, int& c2)

{

int strl = str.GetLength();

CString CR, CP, str1;

int strlock = 0;

for (size_t i = 0; i < strl; i++)

{

str1 = "";

str1 = str.Mid(i, 1);

if (str1 != "-")

{

if (!((str1[0] >= '0' && str1[0] <= '9') || (str1[0] >= 'a' && str1[0] <= 'f') || (str1[0] >= 'A' && str1[0] <= 'F')))

{

c1 = -1; return -1;

}//取反就是找不到上面的就返回一个错误码

}

if (str1 == "-") { strlock = 1; }//控制分离偏色和颜色的开关

if (strlock == 0)

{

CR += str1;

}

if (strlock == 1 && str1 != "-")

{

CP += str1;

}

}

CString strt;

strt.Format("%s%s%s", CR.Mid(4, 2), CR.Mid(2, 2), CR.Mid(0, 2));

c1 = Hex_Conversion_Dec(strt);//进制十六倒十

strt.Format("%s%s%s", CP.Mid(4, 2), CP.Mid(2, 2), CP.Mid(0, 2));

c2 = Hex_Conversion_Dec(strt);

return 0;

}

//图片相似度

int redToGreen(COLORREF& c, int c1, int c2)//把图片二值化

{

//int R = c;// GetRValue(c);//获取c中R的值

CString str;

int b, d;

int R, G, B;

R = GetRValue(c);//获取c中R的值

G = GetGValue(c);//获取c中R的值

B = GetBValue(c);//获取c中R的值

int r1, g1, b1, pr, pg, pb;

r1 = GetRValue(c1);//获取c中R的值

g1 = GetGValue(c1);//获取c中R的值

b1 = GetBValue(c1);//获取c中R的值

pr = GetRValue(c2);//获取c中R的值

pg = GetGValue(c2);//获取c中R的值

pb = GetBValue(c2);//获取c中R的值

{

if (pr >= 1)

{

b = r1;

r1 += pr;//最大偏移

pr = b - pr;//最小偏移

if (r1 > 255) {

r1 = 255;//控制数据溢出

}

else if (r1 < 0) {

r1 = 0;//控制数据溢出

}

if (pr > 255)

{

pr = 255;//控制数据溢出

}

else if (pr < 0) {

pr = 0;//控制数据溢出

}

if (R > r1 || R < pr)

{

return 0;

}

}

else if (pr == 0)

{

if (R != r1)

{

return 0;

}

}

}

{

if (pg >= 1)

{

if (pg >= 1)

{

b = g1;

g1 += pg;//最大偏移

pg = b - pg;//最小偏移

if (g1 > 255) {

g1 = 255;//控制数据溢出

}

else if (g1 < 0) {

g1 = 0;//控制数据溢出

}

if (pg > 255)

{

pg = 255;//控制数据溢出

}

else if (pg < 0) {

pg = 0;//控制数据溢出

}

if (G > g1 || G < pg)

{

return 0;

}

}

else if (pg == 0) { if (G != g1) { return 0; } }

}

}

{

if (pb >= 1)

{

b = b1;

b1 += pb;//最大偏移

pb = b - pb;//最小偏移

if (b1 > 255) {

b1 = 255;//控制数据溢出

}

else if (b1 < 0) {

b1 = 0;//控制数据溢出

}

if (pb > 255)

{

pb = 255;//控制数据溢出

}

else if (pb < 0) {

pb = 0;//控制数据溢出

}

if (B > b1 || B < pb)

{

return 0;

}

}

else if (pb == 0) { if (B != b1) { return 0; } }

}

return 1;

}

//原文链接:https ://blog.csdn.net/qq_43345204/article/details/83476693

void Getcol_a(CString str, int& a, int& b)

{

CString utoa, utoa1;

int inlock = 0;

CString str1;

int strl = str.GetLength();

for (size_t i = 0; i < strl; i++)

{

str1 = str.Mid(i, 1);

if (str1 == "-")

{

inlock = 1;

}

if (inlock == 0)

{

utoa += str1;

str1 = "";

}

if (inlock == 1 && str1 != "-")

{

utoa1 += str1;

str1 = "";

}

}

a = StrToInt(utoa);

b = StrToInt(utoa1);

}

int TKdmsoft::FindStr(int x1, int y1, int x2, int y2, const char* str, const char* color_format, int& X, int& Y)

{

//CBitmap, HBitmap, BITMAP.

if (g_hwnd==0)

{

return -1;

}

HDC hDC = GetWindowDC(g_hwnd);// ::GetWindowDC(hwnd);//获取DC

HDC hDCMem = ::CreateCompatibleDC(hDC);//创建兼容DC

RECT rect;

rect.right = y2 - y1;//获取屏幕高度

rect.bottom = x2 - x1;//获取屏幕宽度

HBITMAP hBitMap = ::CreateCompatibleBitmap(hDC, rect.right, rect.bottom);//创建兼容位图

HBITMAP hOldMap = (HBITMAP)::SelectObject(hDCMem, hBitMap);//将位图选入DC。并保存返回值

::BitBlt(hDCMem, 0, 0, rect.right, rect.bottom, hDC, 8+x1,31+y1, SRCCOPY);//将屏幕DC的图象拷贝到内存DC中

CImage bm;

bm.Attach(hBitMap);

//bm.Save("d:\\2345.bmp");//假设文件后缀为.bmp,则保存为为bmp格式

CDC* pDC = CDC::FromHandle(hDCMem);

int width, high;

width = x2 - x1;//bm.GetWidth();//获取图像的宽度

high = y2 - y1; //bm.GetHeight();//获取图像的高度

if (width <= 0 || high <= 0)

{

return -1;

}

int c1, c2;

char** FindStrpm = (char**) new char*[width+100]; //分配一个数组来装图片像数

for (size_t i = 0; i < width+100; i++)

{

FindStrpm[i] = new char[high+100];

}

if (QSC(color_format, c1, c2) == -1)//取回颜色和偏色的数值

{

return -1;

}

COLORREF cor;

int a = 0;

int R = 0, G = 0, B = 0;

for (size_t y = 0; y < width; y++)

{

for (size_t x = 0; x < high; x++)

{

if (x==12 && y==25)

{

x = x;

}

cor = pDC->GetPixel(x, y);

//CString str1;

int tpe;

//memcpy(&tpe,&cor,3);

tpe = redToGreen(cor, c1, c2);//转换主屏幕;

if (tpe == -1)

{

return -1;

}

if (tpe==1)

{

tpe = tpe;

}

FindStrpm[x][y] = tpe;

}

}

bm.Detach();

//释放

::DeleteObject(hBitMap);

::DeleteDC(hDCMem);

::DeleteDC(hDC);

//for (size_t i = 0; i < width+100; i++)

//{

// delete[] FindStrpm[i] ;

//}

delete[] FindStrpm;

int uot_x = -1, uot_y = -1;

int w, h;

//GetDict("C0180300600$方$0.0.8$2");

int b = 0, uto=0;

char* chh= NULL;

chh=GetDictWh(str, w, h, uto);

if (w <= 0 || h <= 0)

{

return -1;

}

a = 0;

int** FindS = (int**) new int* [w];

for (int i = 0; i < w; i++)

{

FindS[i] = new int[h];

}

int zthmax = dictwh[0].w;

int ztdex = 0;

for (size_t x = 0; x < w; x++)

{

if (zthmax==0)

{

ztdex++;

zthmax = dictwh[ztdex].w;

}

zthmax--;

for (size_t y = 0; y < h; y++)

{

char ch[2] = { 0 };

if (y<=dictwh[ztdex].h)

{

memcpy(ch, chh + a, 1);

int temp = StrToInt(ch);

FindS[x][y] = temp;

a++;

}

else

{

FindS[x][y] = 0;

}

}

}

delete[] dictwh;

int uto1=0;// = Dict.yxxs, uto1 = 0;//记录找到的有效像数

bool ret = false;

a = 0, b = 0;

for (size_t x = 0; x < width; x++)

{

if (width - x >= w)//宽度大于等于字体宽度才开始寻找不然从下一行开始

{

for (size_t y = 0; y < high; y++)

{

if (high - y >= h)//高度度大于等于字体宽度才开始寻找不然从下一行开始

{

for (size_t yy = 0; yy < w; yy++)

{

for (size_t hh = 0; hh < h; hh++)

{

int xxx = x + yy, yyy = y + hh;

int b1 = FindStrpm[xxx][yyy], b2 = FindS[yy][hh];

if (b2 == 1)

{

if (b1 != b2)

{

uto1 = 0;

a = 0;

ret = false;

uot_x = -1;

uot_y = -1;

break;;

}

else

{

ret = true;

}

if (a == 0 && ret == true)

{

uot_x = x;

uot_y = y;

}

uto1++;

a++;

if (uto1 >= uto)

{

break;

}

}

}

if (uto1 >= uto)

{

break;

}

}

}

if (uto1 >= uto)

{

break;

}

}

}

if (uto1 >= uto)

{

break;

}

}

for (int i = 0; i < w; i++)

{

delete[] FindS[i];

}

delete[] FindS;

if (uot_x >= 0)

{

X = uot_x+x1;

Y = uot_y+y1;

}

else

{

X = -1;

Y = -1;

return 1;

}

return 1;

}

long TKdmsoft::SetDict(char* file)

{

if (file == NULL|| strpath == NULL)

{

return -1;

}

char path[256] = {0};

memcpy(path, strpath,strlen(strpath));

memcpy(path+ strlen(strpath), file, strlen(file));

HANDLE hand =CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

DWORD Len = 0;

ULONGLONG size;

CFileStatus fileStatus;

if (CFile::GetStatus(path,fileStatus))

{

size = fileStatus.m_size;

}

char* str=new char[size];

memset(str, 0, sizeof(str));

ReadFile(hand, str, size, &Len, NULL);

int a = 0;

char bj[3] = {0};

for (UINT64 i = 0; i < Len; i++)

{

memcpy(bj, str + i, 2);

if (strcmp(bj,"\r\n") == 0)

{

a++;

}

}

Dict = new MyDict[a];

DictSize = a;

memset(Dict, 0, sizeof(Dict));

int b = 0,c=0;

char srz[4096] = {0};

for (QWORD i = 0; i < Len; i++)

{

memcpy(bj, str + i, 2);

if (strcmp(bj,"\r\n")!=0&&bj[0]!='\n')

{

srz[b] = str[i];

b++;

}

if (strcmp(bj, "\r\n") == 0)

{

GetDict(c,srz);

c++;

b = 0;

memset(srz,0,sizeof(srz)*sizeof(char));

}

//memset

}

SetDlgItemText(g_hwnd,EDIT_ZT, str);

CloseHandle(hand);

delete[] str;

return 0;

}

long TKdmsoft::SetPath(char* path)

{

if (path==NULL)

{

return -1;

}

if (strlen(path)<=2)

{

return -1;

}

strpath = path;

return 1;

}

int TKdmsoft::GetDict(int dex, const char* str_a)

{

char str[256] = { 0 }, str1[2] = { 0 };

int strl = strlen(str_a);

char Dict1[256] = { 0 }; //要操作字体的点阵

int dit = 0, Nett = 0, czt = 0, cht = 0;

char Neam[256] = { 0 }; //要操作的字符名称

char czs[256] = { 0 };//有效像数

char chs[256] = { 0 };//竖排行数

int strlock = 0;

for (UINT64 i = 0; i < strl; i++)

{

str1[0] = str_a[i];

if (strcmp(str1, "$") == 0)

{

strlock++;

}

if (strlock == 0 && strcmp(str1, "$") != 0)

{

Dict1[dit] = str1[0];

dit++;

str1[0] = 0;

}

if (strlock == 1 && strcmp(str1, "$") != 0)

{

Neam[Nett] = str1[0];

Nett++;

str1[0] = 0;

}

if (strlock == 2 && strcmp(str1, "$") != 0)

{

czs[czt] = str1[0];

czt++;

str1[0] = 0;

}

if (strlock == 3 && strcmp(str1, "$") != 0)

{

chs[cht] += str1[0];

cht++;

str1[0] = 0;

}

}

if (strlen(Dict1) <= 0 || strlen(Neam) <= 0 || strlen(czs) <= 0 || strlen(chs) <= 0)

{

return 0;//读取错误返回0

}

char ch[3] = { 0 };

CString SST=HexToBin(Dict1);//转换到二进制

Dict[dex].Dict = new char[SST.GetLength()];

memset(Dict[dex].Dict, 0, SST.GetLength());

memcpy(Dict[dex].Dict, SST.GetBuffer(), SST.GetLength());

memcpy(ch,Neam,2);

if (!IsChinese(ch))

{

memcpy(Dict[dex].Neam, Neam, 1);

}

else

{

memcpy(&Dict[dex].Neam, Neam, 2);

}

memcpy(ch, czs+4, 4);

Dict[dex].yxxs = StrToInt(ch);//字符转换到整数

Dict[dex].spxs = StrToInt(chs);//这是竖排行数

return 1;

}

int GetDictSize(const char* str)

{

int strl = strlen(str);

int strlock = 0;

int ret = 0;

int b = 0;

for (size_t i = 0; i < strl; i++)

{

char bj[3] = { 0 };

if (strlock==0)

{

if (strl - i >= 1)

{

memcpy(bj, str + i, 2);

}

else

{

memset(bj, 0, sizeof(bj));

memcpy(bj, str + i, 1);

}

if (IsChinese(bj))

{

b++;

ret = i;

strlock = 1;

}

}

if (strlock == 1&&i-ret==1)

{

strlock = 0;

ret = 0;

}

}

strl = strl - b * 2;

b = b + strl;

return b;

}

char* TKdmsoft::GetDictWh(const char* str, int& w, int& h,int& uto)

{

char retstr[4096] = {0};

if (str==NULL)

{

return "";

}

int strl = GetDictSize(str);

ZTsize = strl;

dictwh = new MyDictwh[strl];

int a = 0,hh=0,sst=0,dex=0,b=0;

for (size_t i = 0; i < strl; i++)

{

a = 0;

for (size_t j = 0; j < DictSize; j++)

{

char bj[3] = {0};

memcpy(bj, str , 2);

if (!IsChinese(bj))

{

memcpy(bj, str + j, 1);

}

if (strcmp(Dict[j].Neam, bj) == 0)

{

a = j + 1;

break;

}

}

if (a>0)

{

h = Dict[a-1].spxs;//字体高度

if (h < 11)

{

h = 11;

}

if (hh==0)

{

hh = h;

}

else

{

if (h>hh)

{

hh = h;

}

}

if (sst==0)

{

sst = strlen(Dict[a - 1].Dict);

memcpy(retstr, Dict[a - 1].Dict, sst);

}

else

{

memcpy(retstr+ sst, Dict[a - 1].Dict, strlen(Dict[a - 1].Dict));

sst+= strlen(Dict[a - 1].Dict);

}

b= strlen(Dict[a - 1].Dict) / h;//字体宽度

w += b;

dictwh[dex].w = b;

dictwh[dex].h = h;

uto += Dict[a - 1].yxxs;

a = 0;

}

}

if (hh==0)

{

w = 0;

h = 0;

uto = 0;

dictwh = NULL;

return "";

}

h = hh;

str = retstr;

return retstr;

}

下面是调用的CPP

// FinndstrExDlg.cpp: 实现文件

//

#include "pch.h"

#include "framework.h"

#include "FinndstrEx.h"

#include "FinndstrExDlg.h"

#include "afxdialogex.h"

#include

#include

#include "dlgs.h"

#include "math.h"

#include "stdlib.h"

#include "MFC进制转换.h"

#include "FindstrEx.h"

//#include

TKdmsoft dm;

using namespace std;

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CFinndstrExDlg 对话框

CFinndstrExDlg::CFinndstrExDlg(CWnd* pParent /*=nullptr*/)

: CDialogEx(IDD_FINNDSTREX_DIALOG, pParent)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CFinndstrExDlg::DoDataExchange(CDataExchange* pDX)

{

CDialogEx::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CFinndstrExDlg, CDialogEx)

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(IDC_BUTTON1, &CFinndstrExDlg::OnBnClickedButton1)

ON_BN_CLICKED(IDC_BUTTON2, &CFinndstrExDlg::OnBnClickedButton2)

ON_BN_CLICKED(IDC_BUTTON3, &CFinndstrExDlg::OnBnClickedButton3)

END_MESSAGE_MAP()

// CFinndstrExDlg 消息处理程序

BOOL CFinndstrExDlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动

// 执行此操作

SetIcon(m_hIcon, TRUE); // 设置大图标

SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码

dm.Sethwnd(m_hWnd);//设置需要找字的窗口

CStatic* pwnd = (CStatic*)GetDlgItem(IDC_PIC1); //IDC_STATIC //pwnd->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

pwnd->ModifyStyle(0xf, SS_BITMAP);

HBITMAP bmp = (HBITMAP)::LoadImage(GetModuleHandle(NULL), "d:\\1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

pwnd->SetBitmap(bmp);//打开图片

return TRUE; // 除非将焦点设置到控件,否则返回 TRUE

}

// 如果向对话框添加最小化按钮,则需要下面的代码

// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,

// 这将由框架自动完成。

void CFinndstrExDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialogEx::OnPaint();

}

}

//当用户拖动最小化窗口时系统调用此函数取得光标

//显示。

HCURSOR CFinndstrExDlg::OnQueryDragIcon()

{

return static_cast(m_hIcon);

}

void CFinndstrExDlg::OnBnClickedButton1()

{

//// TODO: 在此添加控件通知处理程序代码

dm.SetPath("d:\\");

dm.SetDict("找字.txt");

CString cstr,str;

//GetDlgItemText(EDIT_x, cstr);

//cstr.Format("点阵信息:%s\r\n字符名称:%s\r\n有效像数:%d\r\n竖排行数:%d", Dict.Dict, Dict.Neam, Dict.yxxs, Dict.spxs);

//GetDlgItemText(EDIT_y, str);

int x=-1, y=-1;

//time_t t; time(&t);

//tm* m=localtime(&t);

//

//int sbb= m->tm_sec;

dm.FindStr(0, 1, 215, 113, "方方", "ff0000-050505", x, y);

if (x>=0)

{

str.Format("%d", x);

SetDlgItemText(EDIT_x, str);

str.Format("%d", y);

SetDlgItemText(EDIT_y, str);

}

//intTo101(0xC0180300600);

// time(&t);

//m = localtime(&t);

//int sbb1 = m->tm_sec;

//str.Format("%d", sbb1- sbb);

//AfxMessageBox(str);

//CString str= HexToBin("C0180300600");

//SetDlgItemText(EDIT_ZT, g_str1);

//SetDlgItemText(EDIT1_ARRAY, g_str);

//原文链接:https ://blog.csdn.net/mengsuifengc/article/details/109228725

}

void CFinndstrExDlg::OnBnClickedButton2()

{

// TODO: 在此添加控件通知处理程序代码

CString str;

GetDlgItemText(EDIT_ZT, str);

str=BinToHex(str);

SetDlgItemText(EDIT_ZT, str);

}

void CFinndstrExDlg::OnBnClickedButton3()

{

// TODO: 在此添加控件通知处理程序代码

dm.CloseTk();

}

还不是很完善大家自己完善了!

相关推荐

世界战争英雄下载方法、氪金方法、常见问题等(简易入门指南)
Flyme 5深度解析:Android 6.0系统升级后的新体验与挑战
国产榴莲哪里产的 国产榴莲产地
365游戏盒子

国产榴莲哪里产的 国产榴莲产地

09-14 👁️ 9601