当前位置: 首页 > news >正文

用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

转载于:https://www.cnblogs.com/gameprogram/p/5043894.html

相关文章:

  • 高仿微信5.2.1主界面及消息提醒功能
  • 自定义DialogAlert对话框并实现对话框的复用
  • webservice作用(优,缺点;作用)
  • 如何修改Eclipse的背景颜色
  • 编程的智慧
  • 如何修改eclipse快捷键的组合方式
  • 在Application_Error获取Asp.Net未处理异常信息
  • Bmob的使用案例
  • easyui
  • Eclipse导入library的时候报:Found 2 versions of android-support-v4.jar in the dependency list
  • tomcat为什么无法关闭
  • Android项目编译的时候出现:Caused by: java.lang.ClassNotFoundException: com.example.aaa.MainActivity
  • dsadsa
  • 在一个千万级的数据库查寻中,如何提高查询效率?
  • SQLHelp帮助类
  • 【mysql】环境安装、服务启动、密码设置
  • 0基础学习移动端适配
  • Android Volley源码解析
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • angular组件开发
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • PhantomJS 安装
  • QQ浏览器x5内核的兼容性问题
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • vue-router 实现分析
  • 大整数乘法-表格法
  • 当SetTimeout遇到了字符串
  • 前端之Sass/Scss实战笔记
  • 前端知识点整理(待续)
  • 使用SAX解析XML
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 新书推荐|Windows黑客编程技术详解
  • 一些css基础学习笔记
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • NLPIR智能语义技术让大数据挖掘更简单
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #QT(TCP网络编程-服务端)
  • #宝哥教你#查看jquery绑定的事件函数
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (2)MFC+openGL单文档框架glFrame
  • (C++17) optional的使用
  • (MATLAB)第五章-矩阵运算
  • (NSDate) 时间 (time )比较
  • (二)换源+apt-get基础配置+搜狗拼音
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (六)软件测试分工
  • (三)mysql_MYSQL(三)
  • (四)Linux Shell编程——输入输出重定向
  • (一)Java算法:二分查找
  • (原)本想说脏话,奈何已放下
  • (转)关于多人操作数据的处理策略
  • .NET Core 和 .NET Framework 中的 MEF2