用Unity寫一個12306驗證器的惡搞圖生成軟件

前言html

前一陣子是買火車票的高峯期,而後12306的驗證碼就遭到各類吐槽。其實大部分驗證碼沒有那麼難,你們只是由於買不到票git

發泄一下不滿的情緒。因而各類惡搞的圖就出現了,好比找二次元里人物的矮子,找好男人什麼的。。。github

想一想每次都要打開PS調整位置,作爲程序怎麼能忍,因而想寫個程序來更作這個事,正好也想試試Unity在作工具這方面是否方便。web

最後會放上源碼~有須要的能夠拿去繼續改進哈哈。算法

 

第一步windows

 首先整理一下需求:工具

1.顯示八個圖片,須要能自行導入測試

2.能夠編輯的目標文字(就是全部的XXX)字體

3.能夠截圖保存(固然你本身使用QQ截圖也能夠。。)spa

是否是很簡單。。。

 

第二步

開始打開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

相關文章
相關標籤/搜索