• 找茬游戏


    找茬游戏

    最近在整理硬盘时,看到了几年前写的 美女找茬工具,一时兴起看下现在是否能用,试了下,完全用不了了,界面和以前的界面一样啊,图片的偏移应该没有变,按道理应该能用,猜想可能是图片做了处理。就花了点时间看了下,果然发现了问题,现在和大家分享下。

    原理

    找茬游戏是给出两种图片,图片中只有几处地方不同,快速找到不同地方的游戏。原理是通过程序拿到两种图片,然后逐像素对比来找到不同地方。

    图片获取

    1. hMainWnd = ::FindWindow(NULL, L”大家来找茬”)); // 拿到找茬的窗口handle,是需要管理员权限
    2. hDC = GetDC(hMainWnd); // 获取找茬的Device Context
    3. BitBlt(desDC, desX, desY, width, height, srcDC, srcX, srcY, SRCCOPY); // 该函数是从hDC上从(srcX, srcY)拷贝[width, height]像素到desDC中(desX, desY)指定的位置

    一些细节上的东西,可能更需要时间,如找图片的偏移地址,我可以采用的方法是:截图,然后用系统自带的图片编辑器放大来看。

    图片对比

    此时已经拿到两种图片,就需要对像素进行对比,若相同不处理,若不同则将该像素设置为红色,这样方便我们看到不同的地方。

    for (int i = 0; i < mWidth; i++) {
        for (int j = 0; j < mHeight; j++) {
            COLORREF left = GetPixel(hMemDc, i, j); // 取左边图片像素
            COLORREF right = GetPixel(hMemDc, i + delta, j); // 取右边图片像素
            bool isEqual = ComparePixel(left, right); // 像素对比
            if (!isEqual) {
                SetPixel(hMemDc, i, j, 0x00FF); // 设置为红色,当然其他颜色也可以,主要是容易看到差异
            }
        }
    }
    
    /**
     *像素对比函数, 早期版本图片相同的地方像素值都是一样的,用left == right来判断就行,
     *最新的版本上这种方式已经不可以了,对每个像素都做了处理,处理的原则肯定是保证视觉上没有差异,
     *找个几个例子发现,每个字节的高位进行了加一或者减一处理,低位进行了加减4的处理,
     *我们处理方式是每个字节不判断低位,只判断高位差异是否为0或者1,若3个字节都满足,则认为像素相同。
     */
    bool CZhaochaDlg::ComparePixel(COLORREF left, COLORREF right) {
        long value = ((left & 0xFF) >> 4) - ((right & 0xFF) >> 4);
        bool low = abs(value) <= 1;
        value = ((left & 0xFF00) >> 12) - ((right & 0xFF00) >> 12);
        bool middle = abs(value) <= 1;
        value = ((left & 0xFF0000) >> 20) - ((right & 0xFF0000) >> 20);
        bool high = abs(value) <= 1;
        return low && middle && high;
    }

    注意地方,可以先将两种图片输出看下是否位置找对了,然后分别输出left和right像素来看,是否偏移delta找对了,只有确保这两个找对的前提下,在逐像素来分析规律。

    工具

    这里写图片描述

    界面主要三部分:
    1. 图片展示,不同地方用红色来标识;
    2. 配置信息,是为了适应以后图片位置的调整,这样就不需要修改程序;
    3. 开始和获取图片,在新开一个找茬窗口或者修改配置信息时,是需要点击”开始”,然后之后每次只需要点击获取图片。

    优化空间

    这里写图片描述

    可以看到,除了几处大的红色部分外,还有小的密密麻麻的红色区域,是个就是应该上述判断方法不能涵盖所有情况引起的,所以还有不少的优化空间,一种方案是将颜色分成用(R,G,B)表示,类似于三位空间(X,Y,Z)一样,求出两点之间的距离,小于某个阈值表示颜色相同。

    源码

    https://github.com/W-WTerDan/zhaocha

  • 相关阅读:
    彻底理解jdbc为什么用反射创建驱动程序对象
    java反射
    hashcode(),equal()方法深入解析
    面试经验总结
    Spring安全权限管理(Spring Security)
    http认证方式
    ubuntu/linux mint 创建proc文件的三种方法(两)
    cocos2dx使用tolua关于字符串处理的一个问题
    Ubuntu——grub rescue 主引导修复
    BCM wifi分析
  • 原文地址:https://www.cnblogs.com/liwugang/p/7594088.html
Copyright © 2020-2023  润新知