pvz一代特殊圖像格式分析——ptx2X系列(安卓iOS篇)

聲明:本教程內(nèi)容包含:ptx2X系列編碼解碼、ptxPS3系列圖像查看、texTV系列編碼解碼、texiOS系列編碼解碼、txz圖像編碼解碼,若你根據(jù)本教程寫出了對(duì)應(yīng)工具,請(qǐng)務(wù)必注明是參考了本教程。
一代安卓iOS中的ptx圖像共有七種格式,分別為0,1,2,3,21,22,23,其中0,1,2,3不在此討論,下面以解碼ptx22格式為例,給出21,22,23格式分析和編碼解碼代碼實(shí)現(xiàn)
前面是發(fā)現(xiàn)其存儲(chǔ)方式的過程,后面是代碼實(shí)現(xiàn),(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)如果耐心看完,相信你一定能明白原理。
使用iPad Air 2(iOS8系統(tǒng),游戲版本為付費(fèi)HD版1.9.12)截圖游戲加載界面,發(fā)現(xiàn)分辨率為2048*1536,在rsb中ptx信息段搜索00 08 00 00 00 06 00 00(此信息為圖像寬度2048和圖像高度1536的32位十六進(jìn)制小端序表示),發(fā)現(xiàn)所有分(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)辨率為2048*1536的ptx圖像存儲(chǔ)格式均為0x16即22,所以此圖像存儲(chǔ)格式肯定為22。


用PS打開游戲中截圖,放大,對(duì)比左上(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)角顏色,發(fā)現(xiàn)紅框內(nèi)顏色都相同,藍(lán)框內(nèi)顏色都相同,如圖所示

游戲加載界面背景圖像ptx文件大小為6mb=6291456b,而6291456/(2048*1536)=2,也就是說平均每個(gè)像素用2個(gè)字節(jié)存儲(chǔ)。所以先猜測(cè)其存儲(chǔ)圖像方式為rgb565或rgba5551。
用十六進(jìn)制編輯器打開游戲加載界面背景圖像ptx,發(fā)現(xiàn)有很多70 D6和70 DE,其中70 D6就是1101011001110000,而紅框內(nèi)顏(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)色對(duì)應(yīng)r值為11010110,g值為11001111,b值為10000100,r的前五位為11010,g的前六位為110011,b的前五位為10000,拼接在一起正好是1101011001110000,同理藍(lán)框內(nèi)的顏色也對(duì)應(yīng)后面的70 DE,所以圖像存儲(chǔ)格式應(yīng)該是rgb565。正常的rgb565圖像是依次存儲(chǔ)每一行的所有像素的rgb值的,用此方(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)式將圖像轉(zhuǎn)碼為png,發(fā)現(xiàn)得到了亂碼,如圖所示,但主體色調(diào)十分接近截圖色調(diào),所以存儲(chǔ)方式應(yīng)該是rgb565沒錯(cuò),猜測(cè)是游戲做了進(jìn)一步處理。

我們回到十六進(jìn)制編輯器,可以看到兩個(gè)70 D6間隔0x40即64字節(jié),也就是說,圖像rgb信息向右寫了32像素之后轉(zhuǎn)而向下開始寫下一行的rgb信息。莫非這個(gè)圖片是每向右寫16像素的顏色值就換行寫下一行,直到這一列寫完之后(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)去寫下一列的顏色值?按照此猜想寫代碼解碼為png,如圖,還是亂碼,只不過比之前更有規(guī)律了,已經(jīng)能看出來原圖像的部分內(nèi)容了。

為什么會(huì)出現(xiàn)32*32的像素塊?難道是游戲?qū)ⅲú宀ノ恼滤。篵站迎風(fēng)聽雨丶制作討論群1017246977)原圖像分為很多個(gè)32*32的像素塊,然后分別存儲(chǔ)每個(gè)像素塊的值嗎?按照這個(gè)猜想,改進(jìn)了一下程序,竟然解出了正確的原圖像。

所以這個(gè)格式為22的ptx,應(yīng)該就是將圖(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)像分為很多32*32的像素塊,每個(gè)像素塊存儲(chǔ)方式為依次存儲(chǔ)每一行每個(gè)像素的rgb565形式的顏色,然后依次存儲(chǔ)每一個(gè)32*32的像素塊。
下面給出C#代碼實(shí)現(xiàn)。其中,HexReader為我為了處理二進(jìn)制文件方便,自己寫的類,可以直接換成BinaryReader類;LockBitmap類是提供鎖定內(nèi)存法快速實(shí)現(xiàn)讀寫圖像某一點(diǎn)像素的類,可以直接刪去然后使用Bitmap。此方法(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)傳入一個(gè)使用ptx圖像構(gòu)造的HexReader對(duì)象和ptx圖像的寬度高度,返回一個(gè)基于此圖像的Bitmap類,可以直接存儲(chǔ)為文件,也可以在pictureBox控件中顯示。
? ? ? ? //解碼
? ? ? ??static Bitmap Get_R5G6B5C32(HexReader HR, int height, int width)
? ? ? ??{
? ? ? ? ? ? Bitmap img = new Bitmap(width, height);
? ? ? ? ? ? int temp;
? ? ? ? ? ? LockBitmap img2 = new LockBitmap(img);
? ? ? ? ? ? img2.LockBits();
? ? ? ? ? ? for (int i = 0; i < height; i += 32)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? for (int w = 0; w < width; w += 32)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? for (int j = 0; j < 32; j++)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? for (int k = 0; k < 32; k++)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? temp = HR.ReadUInt16(); //(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)
? ? ? ? ? ? ? ? ? ? ? ? ? ? img2.SetPixel(w + k, i + j, Color.FromArgb((temp & 0xF800) >> 8, (temp & 0x7E0) >> 3, (temp & 0x1F) << 3));
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //編碼
? ? ? ? static void Save_R5G6B5C32(HexWriter HW, Bitmap img)
? ? ? ? {
? ? ? ? ? ? int height = img.Height;
? ? ? ? ? ? int width = img.Width;
? ? ? ? ? ? if (height % 32 != 0 || width % 32 != 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? throw new Exception("ptx22格式的圖像高度或?qū)挾葢?yīng)為塊邊長的整數(shù)倍!");
? ? ? ? ? ? }
? ? ? ? ? ? Color temp2;
? ? ? ? ? ? for (int i = 0; i < height; i += 32)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? for (int w = 0; w < width; w += 32)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? for (int j = 0; j < 32; j++) //(插播文章水印:b站迎風(fēng)聽雨丶制作討論群1017246977)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? for (int k = 0; k < 32; k++)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? temp2 = img.GetPixel(w + k, i + j);
? ? ? ? ? ? ? ? ? ? ? ? ? ? HW.WriteUInt16((ushort)(((temp2.B & 0xF8) >> 3) + ((temp2.G & 0xFC) << 3) + ((temp2.R & 0xF8) << 8)));
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
其中C32代表chunk32(按照32*32像素分塊)。
ptx21與ptx23和此原理類似,只不過(插播文章水?。篵站迎風(fēng)聽雨丶制作討論群1017246977)圖像分別使用rgba4444和rgba5551存儲(chǔ),在此不再贅述。
我使用C#寫了支持一代ptx、tex、txz圖像的圖像查看器,可用于查看、編碼、解碼這些圖像,需要下載可加群1017246977獲取。