WPF如何判断PNG中的点是透明的
最近想用WPF做个空战游戏,其中就要解决子弹是否击中飞机的问题。这里面飞机用了PNG图片,大家都知道飞机是不规则图案,如何判断子弹碰撞成了一个难题。
好在我在网上找到了一个可以获取bitmap像素点颜色的方法。获取图像的ARGB 其中A就是透明度 当A等于0的时候就是透明
剩下的问题就是如何把ImageSource转成bitmap以及如何计算Image控件中的点对应的像素点坐标问题了。
废话不多说 直接上代码好了 相信大家是能看懂的。
1 /// <summary> 2 /// 获取Image控件上点对应图像的点是否是透明的 3 /// </summary> 4 /// <param name="p">相对Image控件的点</param> 5 /// <param name="Image_Main">Image控件</param> 6 /// <returns>是否透明</returns> 7 public static Boolean IsPointTransparent(System.Windows.Point p, System.Windows.Controls.Image Image_Main) 8 { 9 if (Image_Main.Source == null) { 10 return true; 11 } 12 BitmapSource m = (BitmapSource)Image_Main.Source; 13 using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(m.PixelWidth, m.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)) 14 { 15 16 System.Drawing.Imaging.BitmapData data = bmp.LockBits( 17 new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 18 m.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride); bmp.UnlockBits(data); 19 int x = -1; 20 int y = -1; 21 double dx = 1; 22 double dy = 1; 23 System.Drawing.Point ImagePoint = new System.Drawing.Point(x, y); 24 25 #region 获取实际图像点 26 27 switch (Image_Main.Stretch) 28 { 29 case Stretch.Fill: 30 dx = bmp.Width / Image_Main.ActualWidth; 31 dy = bmp.Height / Image_Main.ActualHeight; 32 x = int.Parse((p.X * dx).ToString("F0")); 33 y = int.Parse((p.Y * dy).ToString("F0")); 34 ImagePoint.X = x; 35 ImagePoint.Y = y; 36 break; 37 case Stretch.None: 38 x = int.Parse(p.X.ToString("F0")); 39 y = int.Parse(p.Y.ToString("F0")); 40 ImagePoint.X = x; 41 ImagePoint.Y = y; 42 break; 43 case Stretch.Uniform: 44 if (Image_Main.ActualWidth > Image_Main.ActualHeight) 45 { 46 dx = bmp.Width / Image_Main.ActualWidth; 47 dy = (bmp.Height / bmp.Width) * dx; 48 } 49 else 50 { 51 dy = bmp.Height / Image_Main.ActualHeight; 52 dx = (bmp.Width / bmp.Height) * dy; 53 } 54 x = int.Parse((p.X * dx).ToString("F0")); 55 y = int.Parse((p.Y * dy).ToString("F0")); 56 ImagePoint.X = x; 57 ImagePoint.Y = y; 58 break; 59 case Stretch.UniformToFill: 60 if (Image_Main.ActualWidth > Image_Main.ActualHeight) 61 { 62 dx = bmp.Width / Image_Main.ActualWidth; 63 dy = dx; 64 } 65 else 66 { 67 dx = bmp.Height / Image_Main.ActualHeight; 68 dy = dx; 69 } 70 x = int.Parse((p.X * dx).ToString("F0")); 71 y = int.Parse((p.Y * dy).ToString("F0")); 72 ImagePoint.X = x; 73 ImagePoint.Y = y; 74 break; 75 default: break; 76 } 77 78 #endregion 79 80 if (p.X < 0 || p.Y < 0) 81 { 82 return true; 83 } 84 else 85 { 86 byte A = GetARGB(bmp, ImagePoint.X, ImagePoint.Y); 87 if ((int)A == 0) 88 { 89 return true; 90 } 91 else 92 { 93 return false; 94 } 95 } 96 } 97 } 98 99 /// <summary> 100 /// 获取图像对应点的透明度 101 /// </summary> 102 /// <param name="bmp">图像</param> 103 /// <param name="x">x坐标</param> 104 /// <param name="y">y坐标</param> 105 /// <returns>透明度</returns> 106 private static byte GetARGB(Bitmap bmp, int x, int y) 107 { 108 System.Drawing.Color pixelColor = bmp.GetPixel(x, y); 109 //像素点颜色的 Alpha 值 110 byte alpha = pixelColor.A; 111 //颜色的 RED 分量值 112 byte red = pixelColor.R; 113 //颜色的 GREEN 分量值 114 byte green = pixelColor.G; 115 //颜色的 BLUE 分量值 116 byte blue = pixelColor.B; 117 return alpha; 118 }
看看 其实很简单把
主要是网上大部分都是模糊碰撞 思路基本都是大概框一下 然后算交集
这个方法适合判断点碰撞 如果是面碰撞应该也可以 就是需要继续加算法了
如果喜欢本文请留下你的脚印哦
本文版权归本作者所有 未经允许禁止用于商业目的 转载请注明出处!