Problems with draw transparent images on mobile

Source: Internet
Author: User
Tags transparent image

In mobile development, to make the UI more beautiful, some images are indispensable for embellishment. If you directly use the picturebox control provided by. NET Compact framework, there will always be a problem with the background color (I will write another article on how to handle the background transparency control)ArticleSummarize some of my experiences ). Therefore, sometimes the image is directly draw in form or control onpaint.

When draw images are used, some transparent images often need to be processed. In order to ignore the transparent part only when draw is not transparentCodeTo achieve:

Imageattributes attrib = New Imageattributes ();
Bitmap IMG = New Bitmap (path +" \ Test.png ");
Color color = color. transparent; // IMG. getpixel (0, 0 );
Attrib. setcolorkey (color, color );
E. Graphics. drawimage (IMG, New Rectangle (10, 10, IMG. width, IMG. height), 0, 0, IMG. width, IMG. height, graphicsunit. pixel, attrib); this is achieved by setting the imageattributes attribute so that certain colors are not drawn when drawimage is used to ignore values of specific range colors. This method basically meets our requirements for images with clear transparent edges, but it is not ideal for images with blurred effects on transparent edges, in particular, when a transparent image is superimposed on another image. For example, if an image with a transparent background is drawn on a form with a pure white background, the effect is as follows:

This is because the transparent part and the non-transparent part have a gradient and transparency process. You cannot simply filter a certain color value, but you should apply a complicated one.Algorithm. Later, I found two ways on the Internet to solve this problem: the alphablend () function and the image COM Object of the imaging API.

I use image COM for processing, although I feel that the efficiency has declined. First, define some COM interface declarations iimageingfactor:

 Using System; Using System. drawing; Using System. runtime. interopservices; Namespace Sbuxmobile. helper { // Pulled from gdipluspixelformats. h In the Windows Mobile 5.0 Pocket PC SDK      Public   Enum Pixelformatid: Int {Pixelformatindexed = 0x00010000, // Indexes into a palette Pixelformatgdi = 0x00020000, // Is a GDI-supported format Pixelformatalpha = 0x00040000, // Has an Alpha component Pixelformatpalpha = 0x00080000,// Pre-Multiplied alpha Pixelformatextended = 0x00100000, // Extended color 16 bits/Channel Pixelformatcanonical = 0x00200000, pixelformatundefined = 0, pixelformatdontcare = 0, pixelformat1bppindexed = (1 | (1 <8) | pixelformatindexed | pixelformatgdi ), pixelformat4bppindexed = (2 | (4 <8) | pixelformatindexed | pixelformatgdi), pixelformat8bppindexed = (3 | (8 <8) | pixelformatindexed | pixelformatgdi ), pixelformat16bpprgb555 = (5 | (16 <8) | pixelformatgdi), pixelformat16bpprgb565 = (6 | (16 <8) | pixelformatgdi ), pixelformat16bppargb1555 = (7 | (16 <8) | pixelformatalpha | pixelformatgdi), pixelformat24bpprgb = (8 | (24 <8) | pixelformatgdi ), pixelformat32bpprgb = (9 | (32 <8) | pixelformatgdi), pixelformat32bppargb = (10 | (32 <8) | pixelformatalpha | pixelformatgdi | pixelformatcanonical ), pixelformat32bpppargb = (11 | (32 <8) | pixelformatalpha | pixelformatpalpha | pixelformatgdi), pixelformat48bpprgb = (12 | (48 <8) | pixelformatextended ), pixelformat64bppargb = (13 | (64 <8) | pixelformatalpha | pixelformatcanonical | pixelformatextended), bytes = (14 | (64 <8) | pixelformatalpha | pixelformatpalpha | pixelformatextended ), pixelformatmax = 15}// Pulled from imaging. h In the Windows Mobile 5.0 Pocket PC SDK      Public   Enum Bufferdisposalflag: Int {Bufferdisposalflagnone, bufferdisposalflagglobalfree, bufferdisposalflagcotaskmemfree, bufferdisposalflagunmapview} // Pulled from imaging. h In the Windows Mobile 5.0 Pocket PC SDK      Public   Enum Interpolationhint: Int {Interpolationhintdefault, interpolationhintnearestneighbor, interpolationhintbilinear, interpolationhintaveraging, interpolationhintbicubic}// Pulled from gdiplusimaging. h In the Windows Mobile 5.0 Pocket PC SDK      Public   Struct Bitmapdata { Public   Uint Width; Public   Uint Height; Public   Int Stride; Public Pixelformatid pixelformat; Public Intptr scan0; Public Intptr reserved ;}// Pulled from imaging. h In the Windows Mobile 5.0 Pocket PC SDK      Public   Struct Imageinfo { Public   Uint Guidpart1; // I am being lazy here, I don't care at this point about the rawdataformat guid          Public   Uint Guidpart2; // I am being lazy here, I don't care at this point about the rawdataformat guid          Public   Uint Guidpart3;// I am being lazy here, I don't care at this point about the rawdataformat guid          Public   Uint Guidpart4; // I am being lazy here, I don't care at this point about the rawdataformat guid          Public Pixelformatid pixelformat; Public   Uint Width; Public   Uint Height; Public   Uint Tilewidth; Public  Uint Tileheight; Public   Double Xdpi; Public   Double Ydpi; Public   Uint Flags ;} // Pulled from imaging. h In the Windows Mobile 5.0 Pocket PC SDK [Comimport, GUID (" 327abda7-072b-11d3-9d7b-440f81ef32e "), Interfacetype (cominterfacetype. interfaceisiunknown)] [comvisible ( True )] Public  Interface Iimagingfactory { Uint Createimagefromstream (); // This Is A Place Holder, note the lack of arguments          Uint Createimagefromfile ( String Filename, Out Iimage image ); // We need the specified alas attribute here to keep com InterOP from sending the buffer down as a safe array.          Uint Createimagefrombuffer ([financialas (unmanagedtype. lparray)] Byte [] Buffer, Uint Size, bufferdisposalflag disposalflag, Out Iimage image ); Uint Createnewbitmap ( Uint Width, Uint Height, pixelformatid pixelformat, Out Ibitmapimage Bitmap ); Uint Createbitmapfromimage (iimage image, Uint Width, Uint Height, pixelformatid pixelformat, interpolationhint hints, Out Ibitmapimage Bitmap ); Uint Createbitmapfrombuffer (); // This Is A Place Holder, note the lack of arguments          Uint Createimagedecoder (); // This Is A Place Holder, note the lack of arguments          Uint Createimageencodertostream (); // This Is A Place Holder, note the lack of arguments          Uint Createimageencodertofile (); // This Is A Place Holder, note the lack of arguments          Uint Getinstalleddecoders (); // This Is A Place Holder, note the lack of arguments         Uint Getinstalledencoders (); // This Is A Place Holder, note the lack of arguments          Uint Installimagecodec (); // This Is A Place Holder, note the lack of arguments          Uint Uninstallimagecodec (); // This Is A Place Holder, note the lack of arguments } // Pulled from imaging. h In the Windows Mobile 5.0 Pocket PC SDK [Comimport, GUID (" 327abda9-072b-11d3-9d7b-109f81ef32e "), Interfacetype (cominterfacetype. interfaceisiunknown)] [comvisible (True )] Public   Interface Iimage { Uint Getphysicaldimension ( Out Size ); Uint Getimageinfo ( Out Imageinfo info ); Uint Setimageflags ( Uint Flags ); Uint Draw (intptr HDC, Ref Rectangle dstrect, intptr null );// "Correct" Declaration: uint draw (intptr HDC, ref rectangle dstrect, ref rectangle srcrect );          Uint Pushintosink (); // This Is A Place Holder, note the lack of arguments          Uint Getthumbnail ( Uint Thumbwidth, Uint Thumbheight, Out Iimage thumbimage );} // Pulled from imaging. h In the Windows Mobile 5.0 Pocket PC SDK [Comimport, GUID (" 327abdaa-072b-11d3-9d7b-109f81ef32e "), Interfacetype (cominterfacetype. interfaceisiunknown)] [comvisible (True )] Public   Interface Ibitmapimage { Uint Getsize ( Out Size ); Uint Getpixelformatid ( Out Pixelformatid pixelformat ); Uint Lockbits ( Ref Rectangle rect, Uint Flags, pixelformatid pixelformat, Out Bitmapdata lockedbitmapdata );Uint Unlockbits ( Ref Bitmapdata lockedbitmapdata ); Uint Getpalette (); // This Is A Place Holder, note the lack of arguments          Uint Setpalette (); // This Is A Place Holder, note the lack of arguments }}

Then define a method to draw a transparent image:

         Internal   Static   Void Drawalphaimage (Graphics GR, String Absolutepath, rectangle destrec ){ If (! String. isnullorempty (absolutepath) {iimage alphaimage; iimagingfactory factory = (iimagingfactory) activator. createinstance (type. gettypefromclsid ( New GUID (" 327abda8-072b-11d3-9d7b-440f81ef32e "); Factory. createimagefromfile (absolutepath, Out Alphaimage ); If (Alphaimage! = Null ) {Intptr hdcdest = gr. gethdc (); rectangle dstrect = New Rectangle (destrec. Left, destrec. Top, destrec. Right, destrec. Bottom); alphaimage. Draw (hdcdest, Ref Dstrect, intptr. Zero); gr. releasehdc (hdcdest );}}}

Note:In the iimage. Draw method, the destrect parameter defines the left, top, right, and bottom positions of the target area of the image, rather than the meaning of the traditional left, top, width, and height.

The following figure shows the effect of the image drawn in this way:

When using this method, another problem occurs, that is, the drawimage method is used in many places in the project, and a public function is implemented for processing:

Internal Static VoidDrawimagetransparent (Graphics GR, image, rectangle destrec ){If(Image! =Null) {Imageattributes IA =NewImageattributes (); IA. setcolorkey (color. transparent, color. transparent); gr. drawimage (image, destrec, 0, 0, image. width, image. height, graphicsunit. pixel, Ia );}}

So I want to directly change this method to image COM, so that I don't need to modify the code in other places. However, the image parameter passed in by this method is an image object instead of an image file path. Therefore, factory. createimagefromfile cannot be used in image COM, instead of factory. createimagefrombuffer. That is, first convert the image parameter object to byte [], and then call factory. createimagefrombuffer to generate iimage.

 Internal  Static   Void Drawimagetransparent (Graphics GR, image, rectangle destrec ){ If (Image! = Null ) {Memorystream MS = New Memorystream (); image. Save (MS, imageformat. PNG ); Byte [] Imgbuffer = Ms. getbuffer (); iimage alphaimage; iimagingfactory factory = (iimagingfactory) activator. createinstance (type. gettypefromclsid ( New GUID (" 327abda8-072b-11d3-9d7b-440f81ef32e "); Factory. createimagefrombuffer (imgbuffer ,( Uint ) Imgbuffer. length, bufferdisposalflag. bufferdisposalflagglobalfree, Out Alphaimage ); If (Alphaimage! = Null ) {Intptr hdcdest = gr. gethdc (); rectangle dstrect = New Rectangle (destrec. Left, destrec. Top, destrec. Right, destrec. Bottom ); // Alphaimage. setimageflags (imageflags. imageflagshasalpha ); Alphaimage. Draw (hdcdest, Ref Dstrect, intptr. Zero); gr. releasehdc (hdcdest );}}}

However, the rendered image does not filter the transparent part. The transparent part is still filled with a white background, for example:

I doubt whether it is necessary to set imageflags, but an exception is always thrown when this sentence is run after the setimageflags method is used.The parameter is incorrect. I have also tried to read image files directly into the memory using filestream, but still failed.

 
Filestream F =NewFilestream (path + @"\ Resources \ B .png", Filemode. Open );Byte[] B =New Byte[F. Length]; f. Write (B, 0 ,(Int) F. Length );
 
I wonder if you are familiar with COM or not?
 
 
 
[Useful references]
1. creating transparent GIF images
 
2. alphablending with netcf
 
3. Alpha Mixing under. Net cf
 
4. Alpha mobile controls
 
5. Windows Mobile-attractive mobile part-II
 
6. A solution for transparent images on Compact framework
 
7. aliasing in transparent images (a thread discussed the topic)


 

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.