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         }
View Code

看看 其实很简单把 

主要是网上大部分都是模糊碰撞 思路基本都是大概框一下 然后算交集

这个方法适合判断点碰撞 如果是面碰撞应该也可以 就是需要继续加算法了

如果喜欢本文请留下你的脚印哦

本文版权归本作者所有 未经允许禁止用于商业目的 转载请注明出处!

原文地址:https://www.cnblogs.com/lgmbk/p/7765021.html