在Windows Mobile 显示透明 PNG的方法

同样在移植的过程中,发现 .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 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatIndexed | PixelFormatGDI),
PixelFormat4bppIndexed   = (2 | ( 4 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatIndexed | PixelFormatGDI),
PixelFormat8bppIndexed   = (3 | ( 8 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatIndexed | PixelFormatGDI),
PixelFormat16bppRGB555   = (5 | (16 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatGDI),
PixelFormat16bppRGB565   = (6 | (16 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatGDI),
PixelFormat16bppARGB1555 = (7 | (16 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatAlpha | PixelFormatGDI),
PixelFormat24bppRGB      = (8 | (24 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatGDI),
PixelFormat32bppRGB      = (9 | (32 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatGDI),
PixelFormat32bppARGB     = (10 | (32 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical),
PixelFormat32bppPARGB    = (11 | (32 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI),
PixelFormat48bppRGB      = (12 | (48 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatExtended),
PixelFormat64bppARGB     = (13 | (64 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | PixelFormatAlpha  | PixelFormatCanonical | PixelFormatExtended),
PixelFormat64bppPARGB    = (14 | (64 << <img class="wp-smiley" alt="8)" src="http://www.imobilebbs.com/wordpress/wp-includes/images/smilies/icon_cool.gif"> | 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);

文档可参考 http://msdn.microsoft.com/en-us/library/aa452202.aspx

另外一种方法还是采用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);

最终结果如下图

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值