找回密码
 FreeOZ用户注册
查看: 2046|回复: 2
打印 上一主题 下一主题

Net compact Framework居然不支持透明 PNG

[复制链接]
跳转到指定楼层
1#
发表于 12-10-2010 01:01:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
才发现 .Net compact Framework居然不支持透明 PNG.太弱了。
回复  

使用道具 举报

2#
 楼主| 发表于 13-10-2010 14:33:19 | 只看该作者
In case someone run into same problem, there's one solution for this problem.

it uses IImagingFactory etc to solve this problem.

AlphaExample.zip

82.22 KB, 下载次数: 2

回复  

使用道具 举报

3#
 楼主| 发表于 13-10-2010 18:40:59 | 只看该作者

在Windows Mobile 显示透明 PNG的方法

同样在移植的过程中,发现 .Net compact Framework 不支持透明图像。原本具有透明属性的Png (含有 alpha通道),通过 Graphics.DrawImage 显示之后,不再具有透明特性。这对于地图分层显示带了麻烦。举例来说。带地名卫星地图一般是由两层图片叠加而成。

                               
登录/注册后可看大图

两个图片叠加形成最后的图片


                               
登录/注册后可看大图

当由于.Net Compact Framework缺省不支持透明图像,两幅图叠加是 道路图回彻底覆盖掉下面的卫星图。原来的透明色变成白色。 同样如果再有其它图层(比如路径),又覆盖掉道路图。


经过Google 搜索,有两种方法可以实现在Windows mobile 上透明图像的显示。


一是通过IImagingFactory 接口



  1. using System;
  2. using System.Drawing;
  3. using System.Runtime.InteropServices;
  4. namespace DotNetPocketStreet.Drawing
  5. {
  6. enum ImageLockMode
  7. {
  8. ImageLockModeRead = 0x0001,
  9. ImageLockModeWrite = 0x0002,
  10. ImageLockModeUserInputBuf = 0x0004
  11. };
  12. // Pulled from gdipluspixelformats.h in the Windows Mobile 5.0 Pocket PC SDK
  13. public enum PixelFormatID : int
  14. {
  15. PixelFormatIndexed = 0x00010000, // Indexes into a palette
  16. PixelFormatGDI = 0x00020000, // Is a GDI-supported format
  17. PixelFormatAlpha = 0x00040000, // Has an alpha component
  18. PixelFormatPAlpha = 0x00080000, // Pre-multiplied alpha
  19. PixelFormatExtended = 0x00100000, // Extended color 16 bits/channel
  20. PixelFormatCanonical = 0x00200000,
  21. PixelFormatUndefined = 0,
  22. PixelFormatDontCare = 0,
  23. PixelFormat1bppIndexed = (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI),
  24. PixelFormat4bppIndexed = (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI),
  25. PixelFormat8bppIndexed = (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI),
  26. PixelFormat16bppRGB555 = (5 | (16 << 8) | PixelFormatGDI),
  27. PixelFormat16bppRGB565 = (6 | (16 << 8) | PixelFormatGDI),
  28. PixelFormat16bppARGB1555 = (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI),
  29. PixelFormat24bppRGB = (8 | (24 << 8) | PixelFormatGDI),
  30. PixelFormat32bppRGB = (9 | (32 << 8) | PixelFormatGDI),
  31. PixelFormat32bppARGB = (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical),
  32. PixelFormat32bppPARGB = (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI),
  33. PixelFormat48bppRGB = (12 | (48 << 8) | PixelFormatExtended),
  34. PixelFormat64bppARGB = (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended),
  35. PixelFormat64bppPARGB = (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended),
  36. PixelFormatMax = 15
  37. }
  38. // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
  39. public enum BufferDisposalFlag : int
  40. {
  41. BufferDisposalFlagNone,
  42. BufferDisposalFlagGlobalFree,
  43. BufferDisposalFlagCoTaskMemFree,
  44. BufferDisposalFlagUnmapView
  45. }
  46. // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
  47. public enum InterpolationHint : int
  48. {
  49. InterpolationHintDefault,
  50. InterpolationHintNearestNeighbor,
  51. InterpolationHintBilinear,
  52. InterpolationHintAveraging,
  53. InterpolationHintBicubic
  54. }
  55. // Pulled from gdiplusimaging.h in the Windows Mobile 5.0 Pocket PC SDK
  56. public struct BitmapData
  57. {
  58. public uint Width;
  59. public uint Height;
  60. public int Stride;
  61. public PixelFormatID PixelFormat;
  62. public IntPtr Scan0;
  63. public IntPtr Reserved;
  64. }
  65. // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
  66. public struct ImageInfo
  67. {
  68. public uint GuidPart1; // I am being lazy here, I don't care at this point about the RawDataFormat GUID
  69. public uint GuidPart2; // I am being lazy here, I don't care at this point about the RawDataFormat GUID
  70. public uint GuidPart3; // I am being lazy here, I don't care at this point about the RawDataFormat GUID
  71. public uint GuidPart4; // I am being lazy here, I don't care at this point about the RawDataFormat GUID
  72. public PixelFormatID pixelFormat;
  73. public uint Width;
  74. public uint Height;
  75. public uint TileWidth;
  76. public uint TileHeight;
  77. public double Xdpi;
  78. public double Ydpi;
  79. public uint Flags;
  80. }
  81. // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
  82. [ComImport, Guid("327ABDA7-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  83. [ComVisible(true)]
  84. public interface IImagingFactory
  85. {
  86. uint CreateImageFromStream(); // This is a place holder, note the lack of arguments
  87. uint CreateImageFromFile(string filename, out INativeImage image);
  88. // We need the MarshalAs attribute here to keep COM interop from sending the buffer down as a Safe Array.
  89. uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint size, BufferDisposalFlag disposalFlag, out INativeImage image);
  90. uint CreateNewBitmap(uint width, uint height, PixelFormatID pixelFormat, out IBitmapImage bitmap);
  91. uint CreateBitmapFromImage(INativeImage image, uint width, uint height, PixelFormatID pixelFormat, InterpolationHint hints, out IBitmapImage bitmap);
  92. uint CreateBitmapFromBuffer(); // This is a place holder, note the lack of arguments
  93. uint CreateImageDecoder(); // This is a place holder, note the lack of arguments
  94. uint CreateImageEncoderToStream(); // This is a place holder, note the lack of arguments
  95. uint CreateImageEncoderToFile(); // This is a place holder, note the lack of arguments
  96. uint GetInstalledDecoders(); // This is a place holder, note the lack of arguments
  97. uint GetInstalledEncoders(); // This is a place holder, note the lack of arguments
  98. uint InstallImageCodec(); // This is a place holder, note the lack of arguments
  99. uint UninstallImageCodec(); // This is a place holder, note the lack of arguments
  100. }
  101. // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
  102. [ComImport, Guid("327ABDA9-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  103. [ComVisible(true)]
  104. public interface INativeImage
  105. {
  106. uint GetPhysicalDimension(out Size size);
  107. uint GetImageInfo(out ImageInfo info);
  108. uint SetImageFlags(uint flags);
  109. uint Draw(IntPtr hdc, ref Rectangle dstRect, IntPtr NULL); // "Correct" declaration: uint Draw(IntPtr hdc, ref Rectangle dstRect, ref Rectangle srcRect);
  110. uint PushIntoSink(); // This is a place holder, note the lack of arguments
  111. uint GetThumbnail(uint thumbWidth, uint thumbHeight, out INativeImage thumbImage);
  112. }
  113. // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
  114. [ComImport, Guid("327ABDAA-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  115. [ComVisible(true)]
  116. public interface IBitmapImage
  117. {
  118. uint GetSize(out Size size);
  119. uint GetPixelFormatID(out PixelFormatID pixelFormat);
  120. uint LockBits(ref Rectangle rect, uint flags, PixelFormatID pixelFormat, out BitmapData lockedBitmapData);
  121. uint UnlockBits(ref BitmapData lockedBitmapData);
  122. uint GetPalette(); // This is a place holder, note the lack of arguments
  123. uint SetPalette(); // This is a place holder, note the lack of arguments
  124. }
  125. }
复制代码


调用方法如下



  1.           using (Graphics gxBuffer = Graphics.FromImage(backBuffer))
  2.                 {
  3.                     // Since we nop'd OnPaintBackground, take care of it here
  4.                     gxBuffer.Clear(this.BackColor);
  5.                     // Ask the Image object from Imaging to draw itself.
  6.                     IntPtr hdcDest = gxBuffer.GetHdc();
  7.                     Rectangle dstRect = new Rectangle(100, 100, 148, 148);
  8.                     imagingResource.Draw(hdcDest, ref dstRect, IntPtr.Zero);
  9.                     gxBuffer.ReleaseHdc(hdcDest);
  10.                     // Ask the Image object from Imaging to draw itself.
  11.                     /*IntPtr*/ hdcDest = gxBuffer.GetHdc(); // This is redundant, but keeps the necessary code together
  12.                     /*Rectangle*/ dstRect = new Rectangle(50, 70, 50+132, 70+132);
  13.                     imagingImage.Draw(hdcDest, ref dstRect, IntPtr.Zero);
  14.                     gxBuffer.ReleaseHdc(hdcDest);
  15.                 }
  16.                 // Put the final composed image on screen.
  17.                 e.Graphics.DrawImage(backBuffer, 0, 0);
复制代码




另外一种方法还是采用Manged code, 对于预先知道透明色值的图像,比如地图API中的路径,背景色总为0xFFE0E0E0


可以使用下面方法



  1. ImageAttributes _imageAttributes = new ImageAttributes();
  2. Color color = Color.FromArgb(0xE0E0E0);
  3. _imageAttributes.SetColorKey(color, color);
  4. Rectangle dstRect = new Rectangle(x, y, netImage.GetWidth(), netImage.GetHeight());
  5. gxBuffer.DrawImage(netImage._bitmap, dstRect, 0, 0, netImage.GetWidth(),
  6.                                                    netImage.GetHeight(),
  7.                                                    GraphicsUnit.Pixel, _imageAttributes);
复制代码

最终结果如下图:



                               
登录/注册后可看大图


[ 本帖最后由 trisun 于 13-10-2010 18:43 编辑 ]
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+11, 27-11-2024 17:40 , Processed in 0.036952 second(s), 20 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表