Wince/VC efficient PNG texture, custom Alpha Algorithm

Source: Internet
Author: User

At work, PNG images are required for some dazzling interfaces. Microsoft also provides support for PNG images in wince, but the Alpha mixing speed is relatively slow, therefore, we have implemented an Alpha hybrid operation interface, which is four or five times faster than Microsoft alphablend. Of course, the Alpha hybrid method is also suitable for VC in the window. The test data is shown below.

Original blog, which needs to be reproduced. Please indicate the source:Http://www.cnblogs.com/mythou/p/3150396.html

 

1. Create a 32-Bit Bitmap.

Generally, we use Microsoft's compatible DC and compatible bitmap to process interface textures. However, I need to create a 32-bit device-independent bitmap. (If you are not familiar with DIB bitmap, you can refer to Baidu. This is a bitmap format corresponding to a compatible bitmap. ).

 /* 
* HDC: compatible DC pointer
* Nwidth: The DIB bitmap width needs to be created.
* Nheight: Creates a bitmap height.
* Pbitmapdata: This is my own data type, which is an unsigned char * type.
*/

Hbitmap cpngbitblt: create32bitmap (HDC, Int Nwidth, Int Nheight, hbmdc & Pbitmapdata ){ If (HDC = Null ){ Return NULL ;} If (Nwidth = 0 | Nheight = 0 ){ Return NULL;} bitmapinfo * Pbinfo = New Bitmapinfo; If (! Pbinfo ){ Return NULL;} zeromemory (pbinfo, Sizeof (Bitmapinfo); pbinfo -> Bmiheader. bisize = Sizeof (Bitmapinfoheader); pbinfo -> Bmiheader. biwidth =Nwidth; pbinfo -> Bmiheader. biheight =-nheight; // Bitmap flip Pbinfo-> bmiheader. biplanes = 1 ; Pbinfo -> Bmiheader. bibitcount = 32 ; // 32-Bit Bitmap Byte * Lpbitmapbits = NULL; hbitmap hdibmp = Createdibsection (HDC, pbinfo, dib_rgb_colors ,( Void **) & Lpbitmapbits, null, 0 ); Pbitmapdata = Lpbitmapbits; Delete pbinfo; If (Hdibmp = Null ){ Return NULL ;} Return Hdibmp ;}

The above function creates a DIB bitmap of the specified size and returns the Data Pointer of this bitmap (the first pointer to the bitmap data ).

This bitmap is generally used as a background bitmap. We generally use the dual-buffer method of the texture. We need two bitmaps before and after it. This DIB bitmap is used as a memory DC bitmap.

 

2. Load PNG Images

PNG image loading. Here, I still use Microsoft iimage to decode PNG images. I have used the pnglib decoding library. The actual decoding speed is not as high as that of iimage. It may also be that the libpng library I compiled has not been optimized. Therefore, libpng is temporarily abandoned. We will discuss the principles of libpng decoding and embedded optimization methods in the future. Android uses libpng to decode PNG, so the decoding speed should be good. However, it is estimated that some embedded platforms need to be implemented. The CPU clock speed of most embedded platforms is not high, (the current mobile phone exception -_-!), I usually work in the range of m to M. The following is the decoding part.CodeThe main function is to decode the PNG image from iimage, and then construct a DIB bitmap to obtain a pointer that can operate the image.

Bool cimagedata: loadimagefromfile ( Const Tchar * Filename ){  //  Parameter Validity      If (Filename = Null ){  Return  False ;} //  Create a com instance Hresult hR = NULL;  If (Failed (hR =: cocreateinstance (clsid_imagingfactory, null, clsctx_inproc_server, iid_iimagingfactory ,( Void **)& M_pimagingfactory ))){  Return  False ;}  //  Create an image from a file      If (Failed (hR = m_pimagingfactory-> createimagefromfile (filename ,& M_pimage ))){ Return  False ;}  //  Obtain image information      If (Failed (hR = m_pimage-> getimageinfo (& M_imageinfo ))){  Return  False ;}  //  Get raw data      If (Readimagedata () = False ){  Return  False ;}//...... //  Image information is obtained successfully.      Return  True ;}
 Bool cimagedata: readimagedata (){  //  Used to return results Bool Bret = True;  //  Parameter Validity      If (M_pimage = NULL | m_pimagingfactory = Null ){  Return  False ;}  // Retrieve Original Image Data Rect = { 0 , 0  , M_imageinfo.width, m_imageinfo.height}; bitmapdata. Width = M_imageinfo.width; bitmapdata. Height = M_imageinfo.height; bitmapdata. pixelformat = M_imageinfo.pixelformat; ibitmapimage * Pbitmapimage = NULL; m_pimagingfactory -> Createbitmapfromimage (m_pimage, m_imageinfo.width, m_imageinfo.height, pixfmt_32bpp_argb, interpolationhintdefault ,&Pbitmapimage); pbitmapimage -> Lockbits (& rect, imagelockmoderead, pixfmt_32bpp_argb ,& Bitmapdata );  //  Release old data      If (M_pimgdatabuf! = Null) {Delete [] m_pimgdatabuf; m_pimgdatabuf = NULL ;}  //  Apply for a new space Bret = True; m_pimgdatabuf = New Unsigned Char [M_imageinfo.width * m_imageinfo.height * 4  ];  If (M_pimgdatabuf = Null) {Bret = False;  Goto  Error_end_function ;}  //  Copy Data Bret = True; memcpy (m_pimgdatabuf, bitmapdata. scan0, m_imageinfo.width * M_imageinfo.height * 4  ); Error_end_function: pbitmapimage -> Unlockbits (& Bitmapdata); pbitmapimage -> Release ();  Return  Bret ;} 

 

M_pimgdatabuf is a byte * pointer, a starting pointer pointing to PNG image data. We can use this pointer to operate the PNG image data we just decoded.

 

3. Alpha Mixing

First, let's talk about Alpha mixing. Alpha refers to the transparency of PNG images. Generally, we use PNG images to provide translucent display effects. These translucent effects are available on most of the dazzling interfaces, alpha specifies the image transparency. Generally, the image transparency can be divided into two types.

First, the Alpha value of the entire image. Each pixel uses the same Alpha value.

Second, each pixel uses an independent Alpha value.

For 32-bit PNG images, each pixel value stores its own Alpha value. The 32-bit PNG pixel format: argb8888 is that each value is an 8-bit value.

The basic formula for Alpha mixing is as follows:Alpharesult = Alpha * srcpixel + (1-alpha) * destpixel

The following shows an Alpha mixture.AlgorithmExample.

 
//Supports custom alpha
// Pbackdssrcbmp: The Data Pointer of the background DIB bitmap, that is, the pointer returned by the preceding DIB bitmap pbitmapdata
// M_imgdatabuf: decodes the image above and obtains the Data Pointer of the PNG image to be displayed.
 
 
 //  Supports custom alpha  Void Cimagedata: drawimage (hbmdc pbackdcsrcbmp, Const   Int Dstx, Const   Int Dsty, Const   Int  Alpha, DWORD dstbmp width ){  //  Alpha hybrid operation Byte btalphasrc = 0  ; DWORD isrcpos = 0  ;  Int Idstpos =0  ;  For (DWORD I = 0 ; I <m_imageheigh; I ++ ) {DWORD srcdata = (I + dsty) * dstbmp width + Dstx; DWORD dstdata = I * M_imagewidth;  For ( Int J = 0 ; J <m_imagewidth; j ++ ){  //  Calculate the index of source image data and pixel alpha Isrcpos = (srcdata + J) < 2  ; Idstpos = (Dstdata + J) < 2  ; Btalphasrc = M_pimgdatabuf [idstpos + 3  ]; Btalphasrc = Btalphasrc * alpha> 8  ;  //  Alpha mixing basic formula result = Alpha * srcpixel + (1-alpha) * destpixel Pbackdcsrcbmp [isrcpos] + = (btalphasrc * (m_pimgdatabuf [idstpos]-pbackdcsrcbmp [isrcpos])>8  ); Pbackdcsrcbmp [isrcpos + 1 ] + = (Btalphasrc * (m_pimgdatabuf [idstpos + 1 ]-Pbackdcsrcbmp [isrcpos + 1 ])> 8  ); Pbackdcsrcbmp [isrcpos + 2 ] + = (Btalphasrc * (m_pimgdatabuf [idstpos + 2 ]-Pbackdcsrcbmp [isrcpos + 2 ])> 8  );}}} 
 

The background image and the PNG image to be displayed. The two images correspond to the pixel values. The final image can be obtained by mixing them with Alpha. This is the entire display process.

The method here is not only for PNG images, but also for jpg and BMP images, but these two images generally do not contain Alpha information, so we can only control the transparency of the entire image, the transparency of each pixel cannot be controlled.

The preceding formula is processed to reduce the number of operations and reduce the use of multiplication and division. The comparison between the multiplication and division operations on the CPU is not as good as the addition and subtraction operations.

The following is the result of my own test:

This is the comparison of the running speed on a CPU with a clock speed of MB. The unit of speed is millisecond. We can compare it. Using our Alpha mixture is much faster than Microsoft's alpblend, especially for large images.

I have checked some materials. Most people think that Microsoft's alphablend handles too many exception handling and image scaling operations, resulting in a slow process.

If you need a PNG Paster, You can encapsulate a PNG Paster class based on what I mentioned above. I wrote an article about how to use Microsoft alphblend Paster.Article, Which provides the complete code.

I will not post this custom method because there are many codes.

Microsoft alphablend textures:Http://www.cnblogs.com/mythou/archive/2013/06/13/3133606.html

If you need a friend, you can encapsulate different interfaces as needed. If you do not know anything, you can leave a message.

 

 

You can join a new discussion group if you are interested.

 

VC/wince group: 87053214

 

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.