Disintegration of the school Park 2 and most of the ETC1 compression format of the Unity3d game Package diagram processing

Source: Internet
Author: User

0x0 Background

Well known (?), most (?) Unity3d for the engine. To further compress the resource size, the mapping resource is often compressed in ETC1 format on the Android platform to reduce volume. The egg hurts is that ETC1 does not support alpha channel ....

Program apes choose to split the original image, using a map to record alpha information separately. This brings inconvenience to the subsequent dismantling (stealing) (≧▽≦) (no face). Merge back on the line! righteously

0x1 implementation

The public ... An RGBA image contains three color channels and an alpha channel, which, after splitting, becomes an RGB parameter of the original image record, and an image only records the Alpha parameter.

If the collapse of the unpacking diagram:

So if you want to merge back, you just need to get the RGB values in a graph, get the alpha value in the two graph, and then merge the graphs that generate one by one RGBA messages together to save them.

The language used in this article is C #, first written in an easy-to-understand getpixel () method ~

0x2 Core code-Get pixel method
1 PrivateBitmap mergeimageold (Bitmap rgbtexture,bitmap alphatexture)2 {3Texturewithalpha =NewBitmap (Rgbtexture.width, Rgbtexture.height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);//Create a new bitmap with RGB resolution4     Try5     {6          for(inti =0; i < rgbtexture.width; i++)7         {8              for(intj =0; J < Rgbtexture.height; J + +)9             {TenColor Withalpha =Color.FromArgb (Alphatexture.getpixel (i, J). R, Rgbtexture.getpixel (i, J)); One Texturewithalpha.setpixel (i, J, Withalpha); A}//Internal for End -}//For End -  the         returnTexturewithalpha; -     } -     Catch(Exception ex) -     { + Console.WriteLine (ex. Message); -         returnTexturewithalpha; +     } A}//Mergeimageold ()

Where 6-13 rows are critical code for loop-by-line pixel-wise processing

The overloads used here in line tenth are:

Color Color.FromArgb (int alpha,color basecolor);

The first parameter is the alpha value, the second parameter is the color, alphatexture.getpixel (i, J). R means to get the red component in the alphatexture of line I, J pixels, Rgbtexture.getpixel (i, J) means to get the color in Rgbtexture

Alpha value got, color also got, direct setpixel () just fine ~

0X3 Advanced Code-pointer method

One of the biggest problems with running the above code is ... The chicken is slow .... itself GetPixel () as slow as a snail we also have to getpixel in two pictures () .....

It takes about 2.4 seconds to process a 1.21M 1024*1024-sized picture on my computer.

After flipping through the predecessors ' data, I decided to use the pointer method instead of acquiring pixels

The use of pointers must be checked in the project settings to allow unsafe code and the code that involves the pointer operation must be placed in the unsafe {...} area otherwise not compiled ~

The code is as follows:

1  Public unsafeBitmap mergeimage (Bitmap rgbtexture,bitmap alphatexture)2 {3     intwidth =Rgbtexture.width;4     intHeight =Rgbtexture.height;5 6     Try7     {8BitmapData Texturewithalphadata = Rgbtexture.lockbits (NewRectangle (0,0, width, height), imagelockmode.readwrite, Pixelformat.format32bppargb);//lock an image into memory for Operation9BitmapData Alphatexturedata = Alphatexture.lockbits (NewRectangle (0,0, width, height), imagelockmode.readwrite, Pixelformat.format32bppargb);Ten  One         byte* RESULTP = (byte*) Texturewithalphadata.scan0;//gets the first address in the memory A         byte* Alphap = (byte*) Alphatexturedata.scan0; -  -          for(intj =0; J < height; J + +) the         { -              for(inti =0; I < width; i++) -             { -resultp[3] = alphap[2];//arbg is stored in memory in the order Gbra so resultp[3] is the alpha component Resultp[2] is the red component +RESULTP + =4;//Move down 4 positions to process the next pixel information -Alphap + =4; +             } A         } at  -Rgbtexture.unlockbits (Texturewithalphadata);//Unlock - alphatexture.unlockbits (alphatexturedata); -  -         returnrgbtexture; -     } in     Catch -     { to         returnrgbtexture; +     } -}//mergeimage ()

The 8th line is to note that the second parameter is set to read-write or write-only (imagelockmode.writeonly), and the third parameter is set to 32 bits because it requires a ARGB format with transparent channels AGRB

The 9th line can be set to read-only (imagelockmode.readonly) and because the picture itself is read without an alpha channel, it can be formatted as Pixelformat.format32bpprgb

Line 18th Note that the order of the 32-bit ARGB format bitmap in memory is [g,b,r,a] so the alpha component is actually in the fourth position

Also must pay attention to the release of resources the author put it outside this method or handle the amount of a minute memory explosion

1 rgbtexture.dispose (); 2 alphatexture.dispose (); 3 texturewithalpha.dispose ();
0x4 pointer Method Supplement

The example of this article requires an alpha channel, so the direct use of the 32-bit ARGB format, 32-bit bitmap in four bytes per pixel, the length of each row of data must be a multiple of 4, so do not consider the alignment

The other very common 24-bit graphs each pixel occupies 24/8 = 3, when the length of the data per row is not necessarily a multiple of 4

For a chestnut: a 10 * 10 24-bit picture each row has a data length of 3 * 10 = 30 bytes This will automatically be added to 0 bytes with "32", altogether supplementing 32-30 = 2 bytes

Then if you use pointers in this case to read the data, you must skip the bytes of those bits per row to get the actual number of bytes in the BitmapData class as an attribute bitmapdata.stride

So to process a 24-bit picture, you need to be at the end of the first-level for loop (that is, skip the placeholder bytes at the end of each line as the chestnut above will jump 2 bytes)

The code below can be compared with 0x3

1 byte* RESULTP = (byte*) Texturewithalphadata.scan0;//gets the first address in the memory2 byte* Alphap = (byte*) Alphatexturedata.scan0;3 4 intResultoffset = Texturewithalphadata.stride-width *3;//subtract the length of an effective pixel in a picture by the actual occupied length this line of code is valid only for 24-bit graphs5 intAlphaoffset = Texturewithalphadata.stride-width *3;6 7  for(intj =0; J < height; J + +)8 {9      for(inti =0; I < width; i++)Ten     { Oneresultp[2] = alphap[2];//RBG in memory order for GBR Here's just a handy comparison of chestnuts. This line of code will set the red component of the 2 graph to the 1 graph after running . ARESULTP + =3;//Move down 3 positions to process the next pixel information -Alphap + =3; -     } theRESULTP + = Resultoffset;//because the width of the picture is used above, the pointer stops at the front of the placeholder byte, so it needs to skip too many bytes . -Alphap + =Alphaoffset; -}

0x5 End

Code Address: Https://github.com/yyuueexxiinngg/HSoD2TextureMerge

Extraction tool used: Https://github.com/Perfare/UnityStudio

Time-consuming comparisons in two ways: (Right-click new tab Open)

Disintegration of the school Park 2 and most of the ETC1 compression format of the Unity3d game Package diagram processing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.