zoukankan      html  css  js  c++  java
  • 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

    看看 其实很简单把 

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

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

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

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

  • 相关阅读:
    参加过的面试题目总结
    小论文实验讨论——不同的分类算法
    【设计模式】行为型07备忘录模式(Memento Pattern)
    【设计模式】行为型06命令模式(Command Pattern)
    【设计模式】行为型05责任链模式(Chain of responsibility Pattern)
    【设计模式】行为型04迭代器模式(Iterator Pattern)
    【设计模式】行为型03观察者模式(Observer Pattern)
    【设计模式】行为型02模板方法模式(Template Method Patten)
    【JVM】02垃圾回收机制
    【死磕线程】线程同步机制_java多线程之线程锁
  • 原文地址:https://www.cnblogs.com/lgmbk/p/7765021.html
Copyright © 2011-2022 走看看