• 用Unity写一个12306验证器的恶搞图生成软件


    前言

    前一阵子是买火车票的高峰期,然后12306的验证码就遭到各种吐槽。其实大部分验证码没有那么难,大家只是因为买不到票

    发泄一下不满的情绪。于是各种恶搞的图就出现了,比如找二次元里人物的矮子,找好男人什么的。。。

    想想每次都要打开PS调整位置,做为程序怎么能忍,于是想写个程序来更做这个事,正好也想试试Unity在做工具这方面是否方便。

    最后会放上源码~有需要的可以拿去继续改进哈哈。

     

    第一步

     首先整理一下需求:

    1.显示八个图片,需要能自行导入

    2.可以编辑的目标文字(就是所有的XXX)

    3.可以截图保存(当然你自己使用QQ截图也可以。。)

    是不是很简单。。。

    第二步

    开始打开Unity做了,查资料写代码~

    1.导入图片

    显示图片,只需要弄个背景图,然后在上面用2D的UI放上八上Image即可

    重点在于要导入自己的八张图,这里主要借助Windows的API了,好在Unity提供了调用DLL的方法。

    可以查看下面的Blog操作,我就不重复写了,只写差异化的东西。

    http://www.cnblogs.com/U-tansuo/archive/2012/07/10/GetOpenFileName.html

    在这里遇到一个问题是上面Blog中没法打开多个文件。

    来看一下OpenFileName的结构

    public class OpenFileName 
    {
        public int      structSize = 0;
        public IntPtr   dlgOwner = IntPtr.Zero; 
        public IntPtr   instance = IntPtr.Zero;
        public String   filter = null;
        public String   customFilter = null;
        public int      maxCustFilter = 0;
        public int      filterIndex = 0;
        public String   file = null;
        public int      maxFile = 0;
        public String   fileTitle = null;
        public int      maxFileTitle = 0;
        public String   initialDir = null;
        public String   title = null;   
        public int      flags = 0; 
        public short    fileOffset = 0;
        public short    fileExtension = 0;
        public String   defExt = null; 
        public IntPtr   custData = IntPtr.Zero;  
        public IntPtr   hook = IntPtr.Zero;  
        public String   templateName = null; 
        public IntPtr   reservedPtr = IntPtr.Zero; 
        public int      reservedInt = 0;
        public int      flagsEx = 0;
    }


    问题主要出在file这个记录文件名的变量上,查看了一下MSDN,这个变量在只打开一个文件时是存了文件的文件夹路径+文件名的,

    但是当你多选的时候,它是存了多个隔开的内容的,最前面的是文件夹路径,后面是选择的文件名字。而用string读取时,直接就只取

    到了最前面的文件夹路径名。就此要把它转为指针(IntPtr),然后再去读取。

    List<string> selectedFilesList = new List<string>();
                
    long pointer = (long)ofn.file;
    string file = Marshal.PtrToStringAuto(ofn.file);
                
    // Retrieve file names
    while (file.Length > 0) 
    {
        selectedFilesList.Add(file);
                    
        pointer += file.Length * 2 + 2;
        ofn.file = (IntPtr)pointer;
        file = Marshal.PtrToStringAuto(ofn.file);
    }
                
    string[] slectedfileNames = GetFileNamesByFileList(selectedFilesList);
                
    for (int i = 0; i < slectedfileNames.Length; i++)
    {
        StartCoroutine(WaitLoad(slectedfileNames[i], i));
    }


    那个2其实应该是Char的字节数,用Marshal.SystemDefaultCharSize也是这个值。这样就可以把所有图片的路径都得到了。

    2.编辑文字

    原先我以为12306只是简单的用了个比较特殊的字体,于是我把字体载下来然后去求字体网搜。

    结果没有搜到(平时用这个搜字体还是不错的),应该是加了一些变形算法的字体。为了简便我直接找了个水波字体

    感觉勉强能用。。

    3.截图保存

     这个在Unity里应该算是个很简单的事了,有网友总结了三种方式。

    1.Application.CaptureScreenshot

    2.创建Texture2D,读取屏幕像素

    3.用RenderToTexture来将某个相机所渲染的东西保存到一张Texture中。

    根据需要我选择第二种,又可控又方便。不过目前我也只是拿来载全屏,后面其实可以做到想截哪块截哪块。

    截图的时候记得要隐藏你的编辑用的UI,然后把要截到图里的UI显示出来。在截完后要把编辑用的UI显示出来。

    最后就把截到的图保存到文件中。

        IEnumerator CutImage(string path)
        {
            cutImage = new Texture2D (Screen.width, Screen.height, TextureFormat.ARGB32, true);
    
            Rect rect = new Rect (0, 0, Screen.width, Screen.height);
    
            yield return new WaitForEndOfFrame ();
    
            cutImage.ReadPixels (rect, 0, 0, true);
            cutImage.Apply ();
            yield return cutImage;
    
            byte[] byt = cutImage.EncodeToPNG();  
            //保存截图  
            File.WriteAllBytes(path, byt); 
    
            ChangeToEidtorMode ();
        }

    第三步

    看结果,修细节。嗯······也没啥细节可修的了。

    测试一个:

    写在最后

    本软件纯属娱乐,希望铁道部不会来找我。。。如果你把自己或朋友的十多年的照片整理下让认识的同学来猜,还是挺有

    意思的,直接可以在朋友圈搞个竞猜活动嘛,促进一下感情~还可以把自己想恶搞的东西都放上来,舒缓一下情绪。嗯,这样子想想

    这个软件还是挺有意义的,哈哈~生活如此艰难,我们需要多一些自娱自乐的东西,用程序创造快乐~。

    EXE文件网盘下载:http://pan.baidu.com/s/1i4d0wWP

    github:https://github.com/sunstar1989/12306FunImage

    源码package下载:http://pan.baidu.com/s/1pJZQ0KN

  • 相关阅读:
    Java连接MySql报错—— com.mysql.cj.exceptions.InvalidConnectionAttributeException
    Java——XML基础知识
    Java——多线程基础知识
    Java——线程安全的集合
    Java——集合
    dom4j——使用dom4j生成xml
    Java——用程序编译一个文件夹下所有java文件到另一个文件夹下
    Java——DOS命令窗口用命令编译文件夹下所有.java文件
    Java——删除Map集合中key-value值
    python 枚举Enum
  • 原文地址:https://www.cnblogs.com/gameprogram/p/5043894.html
Copyright © 2020-2023  润新知