同样在移植的过程中,发现 .Net compact Framework 不支持透明图像。原本具有透明属性的Png (含有 alpha通道),通过 Graphics.DrawImage 显示之后,不再具有透明特性。这对于地图分层显示带了麻烦。举例来说。带地名卫星地图一般是由两层图片叠加而成。
两个图片叠加形成最后的图片
当由于.Net Compact Framework缺省不支持透明图像,两幅图叠加是 道路图回彻底覆盖掉下面的卫星图。原来的透明色变成白色。 同样如果再有其它图层(比如路径),又覆盖掉道路图。
经过Google 搜索,有两种方法可以实现在Windows mobile 上透明图像的显示。
一是通过IImagingFactory 接口
-
- using System;
- using System.Drawing;
- using System.Runtime.InteropServices;
- namespace DotNetPocketStreet.Drawing
- {
- enum ImageLockMode
- {
- ImageLockModeRead = 0x0001,
- ImageLockModeWrite = 0x0002,
- ImageLockModeUserInputBuf = 0x0004
- };
- // 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),
- PixelFormat64bppPARGB = (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-0000F81EF32E"), 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 INativeImage image);
- // We need the MarshalAs attribute here to keep COM interop from sending the buffer down as a Safe Array.
- uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint size, BufferDisposalFlag disposalFlag, out INativeImage image);
- uint CreateNewBitmap(uint width, uint height, PixelFormatID pixelFormat, out IBitmapImage bitmap);
- uint CreateBitmapFromImage(INativeImage 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-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [ComVisible(true)]
- public interface INativeImage
- {
- uint GetPhysicalDimension(out Size 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 INativeImage thumbImage);
- }
- // Pulled from imaging.h in the Windows Mobile 5.0 Pocket PC SDK
- [ComImport, Guid("327ABDAA-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [ComVisible(true)]
- public interface IBitmapImage
- {
- uint GetSize(out Size 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
- }
- }
复制代码
调用方法如下
-
- using (Graphics gxBuffer = Graphics.FromImage(backBuffer))
- {
- // Since we nop'd OnPaintBackground, take care of it here
- gxBuffer.Clear(this.BackColor);
- // Ask the Image object from Imaging to draw itself.
- IntPtr hdcDest = gxBuffer.GetHdc();
- Rectangle dstRect = new Rectangle(100, 100, 148, 148);
- imagingResource.Draw(hdcDest, ref dstRect, IntPtr.Zero);
- gxBuffer.ReleaseHdc(hdcDest);
- // Ask the Image object from Imaging to draw itself.
- /*IntPtr*/ hdcDest = gxBuffer.GetHdc(); // This is redundant, but keeps the necessary code together
- /*Rectangle*/ dstRect = new Rectangle(50, 70, 50+132, 70+132);
- imagingImage.Draw(hdcDest, ref dstRect, IntPtr.Zero);
- gxBuffer.ReleaseHdc(hdcDest);
- }
- // Put the final composed image on screen.
- e.Graphics.DrawImage(backBuffer, 0, 0);
复制代码
另外一种方法还是采用Manged code, 对于预先知道透明色值的图像,比如地图API中的路径,背景色总为0xFFE0E0E0
可以使用下面方法
-
- ImageAttributes _imageAttributes = new ImageAttributes();
- Color color = Color.FromArgb(0xE0E0E0);
- _imageAttributes.SetColorKey(color, color);
- Rectangle dstRect = new Rectangle(x, y, netImage.GetWidth(), netImage.GetHeight());
- gxBuffer.DrawImage(netImage._bitmap, dstRect, 0, 0, netImage.GetWidth(),
- netImage.GetHeight(),
- GraphicsUnit.Pixel, _imageAttributes);
复制代码
最终结果如下图:
[ 本帖最后由 trisun 于 13-10-2010 18:43 编辑 ] |