WPF判断两个PNG图片是否碰撞
这个方法有几个前提
1.两个Image必须在一个Canvas中
2.两个Image的Canvas.Top和Canvas.Left必须赋值
上一篇讲了判断一个PNG图片某个点是否透明 这个基本类似的方法
主题思路
1.利用Rect判断两个Image是否有重合
2.只判断重合部分是否存在碰撞
3.将重合区域分成4块 由外向内判定
下面是代码部分
/// <summary>
/// 判断画布上两个Image是否碰撞了
/// </summary>
/// <param name="ig1">Image1</param>
/// <param name="ig2">Image2</param>
/// <returns>是否碰撞</returns>
public static Boolean IsImageInside(System.Windows.Controls.Image ig1, System.Windows.Controls.Image ig2)
{ if (ig1.Source == null || ig2.Source == null)
{
return false;
}
Rect containingRect1 = new Rect(Canvas.GetLeft(ig1), Canvas.GetTop(ig1), ig1.ActualWidth, ig1.ActualHeight);
Rect containingRect2 = new Rect(Canvas.GetLeft(ig2), Canvas.GetTop(ig2), ig2.ActualWidth, ig2.ActualHeight);
containingRect1.Intersect(containingRect2);
if (containingRect1.IsEmpty)
{
return false;
}
System.Windows.Point RectPoint = containingRect1.TopLeft;
BitmapSource m1 = (BitmapSource)ig1.Source;
BitmapSource m2 = (BitmapSource)ig2.Source;
using (System.Drawing.Bitmap bmp1 = new System.Drawing.Bitmap(m1.PixelWidth, m1.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
{ System.Drawing.Imaging.BitmapData data1 = bmp1.LockBits(
new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp1.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
m1.CopyPixels(Int32Rect.Empty, data1.Scan0, data1.Height * data1.Stride, data1.Stride); bmp1.UnlockBits(data1); double dx1 = ;
double dy1 = ; #region 获取实际图像点 #region 获取缩放比例 switch (ig1.Stretch)
{
case Stretch.Fill:
dx1 = bmp1.Width / ig1.ActualWidth;
dy1 = bmp1.Height / ig1.ActualHeight;
break;
case Stretch.None:
break;
case Stretch.Uniform:
if (ig1.ActualWidth > ig1.ActualHeight)
{
dx1 = bmp1.Width / ig1.ActualWidth;
dy1 = (bmp1.Height / bmp1.Width) * dx1;
}
else
{
dy1 = bmp1.Height / ig1.ActualHeight;
dx1 = (bmp1.Width / bmp1.Height) * dy1;
}
break;
case Stretch.UniformToFill:
if (ig1.ActualWidth > ig1.ActualHeight)
{
dx1 = bmp1.Width / ig1.ActualWidth;
dy1 = dx1;
}
else
{
dx1 = bmp1.Height / ig1.ActualHeight;
dy1 = dx1;
}
break;
default: break;
} #endregion int n = ; using (System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(m2.PixelWidth, m2.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
{
System.Drawing.Imaging.BitmapData data2 = bmp2.LockBits(
new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp2.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
m2.CopyPixels(Int32Rect.Empty, data2.Scan0, data2.Height * data2.Stride, data2.Stride); bmp2.UnlockBits(data2); double dx2 = ;
double dy2 = ; #region 获取缩放比例 switch (ig2.Stretch)
{
case Stretch.Fill:
dx2 = bmp2.Width / ig2.ActualWidth;
dy2 = bmp2.Height / ig2.ActualHeight;
break;
case Stretch.None:
break;
case Stretch.Uniform:
if (ig2.ActualWidth > ig2.ActualHeight)
{
dx2 = bmp2.Width / ig2.ActualWidth;
dy2 = (bmp2.Height / bmp2.Width) * dx2;
}
else
{
dy2 = bmp2.Height / ig2.ActualHeight;
dx2 = (bmp2.Width / bmp2.Height) * dy2;
}
break;
case Stretch.UniformToFill:
if (ig2.ActualWidth > ig2.ActualHeight)
{
dx2 = bmp2.Width / ig2.ActualWidth;
dy2 = dx2;
}
else
{
dx2 = bmp2.Height / ig2.ActualHeight;
dy2 = dx2;
}
break;
default: break;
} #endregion double XX1 = Canvas.GetLeft(ig1);
double YY1 = Canvas.GetTop(ig1);
double XX2 = Canvas.GetLeft(ig2);
double YY2 = Canvas.GetTop(ig2);
//double ig1Width = ig1.ActualWidth;
//double ig1Height = ig1.ActualHeight;
double ig1Width = containingRect1.Width;
double ig1Height = containingRect1.Height;
double ig2Width = ig2.ActualWidth;
double ig2Height = ig2.ActualHeight;
Stretch ig1ImageStretchType = ig1.Stretch;
Stretch ig2ImageStretchType = ig2.Stretch;
Boolean isInset = false; #region 线程1 Thread t1 = new Thread(delegate()
{
for (int i = ; i < ig1Width / ; i++)
{
if (isInset)
{
break;
}
for (int j = ; j < ig1Height / ; j++)
{
if (isInset)
{
break;
} #region 判断图像1的点是否透明 System.Windows.Point p1 = new System.Windows.Point(i + RectPoint.X - XX1, j + RectPoint.Y - YY1);
int x1 = -;
int y1 = -;
switch (ig1ImageStretchType)
{
case Stretch.Fill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.None:
x1 = int.Parse(p1.X.ToString("F0"));
y1 = int.Parse(p1.Y.ToString("F0"));
break;
case Stretch.Uniform:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.UniformToFill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
default: break;
}
lock (bmp1)
{
if (x1 < || y1 < || x1 > bmp1.Width || y1 > bmp1.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp1, x1, y1);
if ((int)A == )
{
continue;
}
else
{ }
}
} #endregion #region 判断图像1的点相对于位置的图像2的点是否透明 System.Windows.Point p2 = new System.Windows.Point(XX1 + p1.X - XX2, YY1 + p1.Y - YY2);
int x2 = -;
int y2 = -;
switch (ig2ImageStretchType)
{
case Stretch.Fill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.None:
x2 = int.Parse(p2.X.ToString("F0"));
y2 = int.Parse(p2.Y.ToString("F0"));
break;
case Stretch.Uniform:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.UniformToFill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
default: break;
}
lock (bmp2)
{
if (x2 < || y2 < || x2 > bmp2.Width || y2 > bmp2.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp2, x2, y2);
if ((int)A == )
{
continue;
}
else
{
isInset = true;
break;
}
}
}
#endregion }
}
n = n + ;
}); #endregion #region 线程2 Thread t2 = new Thread(delegate()
{
for (int i = int.Parse(ig1Width.ToString("F0")) - ; i > int.Parse((ig1Width / ).ToString("F0")); i--)
{
if (isInset)
{
break;
}
for (int j = ; j < ig1Height / ; j++)
{
if (isInset)
{
break;
} #region 判断图像1的点是否透明 System.Windows.Point p1 = new System.Windows.Point(i + RectPoint.X - XX1, j + RectPoint.Y - YY1);
int x1 = -;
int y1 = -;
switch (ig1ImageStretchType)
{
case Stretch.Fill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.None:
x1 = int.Parse(p1.X.ToString("F0"));
y1 = int.Parse(p1.Y.ToString("F0"));
break;
case Stretch.Uniform:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.UniformToFill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
default: break;
}
lock (bmp1)
{
if (x1 < || y1 < || x1 > bmp1.Width || y1 > bmp1.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp1, x1, y1);
if ((int)A == )
{
continue;
}
else
{ }
}
} #endregion #region 判断图像1的点相对于位置的图像2的点是否透明 System.Windows.Point p2 = new System.Windows.Point(XX1 + p1.X - XX2, YY1 + p1.Y - YY2);
int x2 = -;
int y2 = -;
switch (ig2ImageStretchType)
{
case Stretch.Fill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.None:
x2 = int.Parse(p2.X.ToString("F0"));
y2 = int.Parse(p2.Y.ToString("F0"));
break;
case Stretch.Uniform:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.UniformToFill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
default: break;
}
lock (bmp2)
{
if (x2 < || y2 < || x2 > bmp2.Width || y2 > bmp2.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp2, x2, y2);
if ((int)A == )
{
continue;
}
else
{
isInset = true;
break;
}
}
}
#endregion }
}
n = n + ;
}); #endregion #region 线程3 Thread t3 = new Thread(delegate()
{
for (int i = ; i < ig1Width / ; i++)
{
if (isInset)
{
break;
}
for (int j = int.Parse(ig1Height.ToString("F0")) - ; j > int.Parse((ig1Height / ).ToString("F0")); j--)
{
if (isInset)
{
break;
} #region 判断图像1的点是否透明 System.Windows.Point p1 = new System.Windows.Point(i + RectPoint.X - XX1, j + RectPoint.Y - YY1);
int x1 = -;
int y1 = -;
switch (ig1ImageStretchType)
{
case Stretch.Fill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.None:
x1 = int.Parse(p1.X.ToString("F0"));
y1 = int.Parse(p1.Y.ToString("F0"));
break;
case Stretch.Uniform:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.UniformToFill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
default: break;
}
lock (bmp1)
{
if (x1 < || y1 < || x1 > bmp1.Width || y1 > bmp1.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp1, x1, y1);
if ((int)A == )
{
continue;
}
else
{ }
}
} #endregion #region 判断图像1的点相对于位置的图像2的点是否透明 System.Windows.Point p2 = new System.Windows.Point(XX1 + p1.X - XX2, YY1 + p1.Y - YY2);
int x2 = -;
int y2 = -;
switch (ig2ImageStretchType)
{
case Stretch.Fill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.None:
x2 = int.Parse(p2.X.ToString("F0"));
y2 = int.Parse(p2.Y.ToString("F0"));
break;
case Stretch.Uniform:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.UniformToFill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
default: break;
}
lock (bmp2)
{
if (x2 < || y2 < || x2 > bmp2.Width || y2 > bmp2.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp2, x2, y2);
if ((int)A == )
{
continue;
}
else
{
isInset = true;
break;
}
}
}
#endregion
}
}
n = n + ;
}); #endregion #region 线程4 Thread t4 = new Thread(delegate()
{
for (int i = int.Parse(ig1Width.ToString("F0")) - ; i > int.Parse((ig1Width / ).ToString("F0")); i--)
{
if (isInset)
{
break;
}
for (int j = int.Parse(ig1Height.ToString("F0")) - ; j > int.Parse((ig1Height / ).ToString("F0")); j--)
{
if (isInset)
{
break;
}
#region 判断图像1的点是否透明 System.Windows.Point p1 = new System.Windows.Point(i + RectPoint.X - XX1, j + RectPoint.Y - YY1);
int x1 = -;
int y1 = -;
switch (ig1ImageStretchType)
{
case Stretch.Fill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.None:
x1 = int.Parse(p1.X.ToString("F0"));
y1 = int.Parse(p1.Y.ToString("F0"));
break;
case Stretch.Uniform:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
case Stretch.UniformToFill:
x1 = int.Parse((p1.X * dx1).ToString("F0"));
y1 = int.Parse((p1.Y * dy1).ToString("F0"));
break;
default: break;
}
lock (bmp1)
{
if (x1 < || y1 < || x1 > bmp1.Width || y1 > bmp1.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp1, x1, y1);
if ((int)A == )
{
continue;
}
else
{ }
}
} #endregion #region 判断图像1的点相对于位置的图像2的点是否透明 System.Windows.Point p2 = new System.Windows.Point(XX1 + p1.X - XX2, YY1 + p1.Y - YY2);
int x2 = -;
int y2 = -;
switch (ig2ImageStretchType)
{
case Stretch.Fill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.None:
x2 = int.Parse(p2.X.ToString("F0"));
y2 = int.Parse(p2.Y.ToString("F0"));
break;
case Stretch.Uniform:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
case Stretch.UniformToFill:
x2 = int.Parse((p2.X * dx2).ToString("F0"));
y2 = int.Parse((p2.Y * dy2).ToString("F0"));
break;
default: break;
}
lock (bmp2)
{
if (x2 < || y2 < || x2 > bmp2.Width || y2 > bmp2.Height)
{
continue;
}
else
{
byte A = GetARGB(bmp2, x2, y2);
if ((int)A == )
{
continue;
}
else
{
isInset = true;
break;
}
}
}
#endregion
}
}
n = n + ;
}); #endregion t1.Start();
t2.Start();
t3.Start();
t4.Start();
while (n != )
{
Thread.Sleep();
}
return isInset;
} #endregion }
}
这个算法我用了连个128X128的图片放到两个200X200的Image中
正常利用VS调试每次判定在150ms左右 不调试直接运行大概在3~10ms之间
电脑配置CPU G1840 内存4G 效率还可以 喜欢的朋友可以参考一下
欢迎大家留下脚印~
本文版权归本作者所有 未经允许禁止用于商业目的 转载请注明出处
WPF判断两个PNG图片是否碰撞的更多相关文章
- WPF判断两个时间大小避免误差
进行查询操作的时候,经常用到判断开始时间和结束时间大小的条件,由于从控件上获取的时间除了年月日时分秒,还包括毫秒.微秒等,导致直接判断时间大小的时候会产生一些误差,如下: 结果分析:年月日时分秒一致的 ...
- WPF 下两种图片合成或加水印的方式(转载)
来源:http://www.cnblogs.com/lxblog/ 最近项目中应用多次应用了图片合成,为了今后方便特此记下. 在WPF下有两种图片合成的方式,一种还是用原来C#提供的GDI+方式,命名 ...
- Java 判断两个对象是否相等
一.使用 == 与 equals == : 它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不是同一个对象.(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) equals() ...
- 如何判断单链表是否存在环 & 判断两链表是否相交
给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针sl ...
- WPF 通过位处理合并图片
原文:WPF 通过位处理合并图片 本文告诉大家,在使用 WPF 合并两张图片的处理,可以使用像素之间的与或和异或的方式,对三个颜色的通道进行处理. 先给大家看一下软件的界面 这就是通过将左边的两张图片 ...
- WPF 判断调用方法堆栈
原文:WPF 判断调用方法堆栈 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客 ...
- WPF和Winform中picturebox图片局部放大
原文:WPF和Winform中picturebox图片局部放大 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/artic ...
- java判断文件是否为图片
/** * 判断文件是否为图片<br> * <br> * @param pInput 文件名<br> * @param pImgeFlag 判断具体文件类型< ...
- 2019-7-22-WPF-如何判断两个-LinearGradientBrush-相等
title author date CreateTime categories WPF 如何判断两个 LinearGradientBrush 相等 lindexi 2019-07-22 21:26:2 ...
随机推荐
- 利用huson的日志获取编译错误信息的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 使用hudson编译一百多个VC工程,输出的日志有6M之大,摆在我面前的一个问题是如何利用这个日志信息来获取编译错误信 ...
- Java8学习之旅2---基于Lambda的JDBC编程
Java8的Lambda表达式确实是一个很好的特性.可是在哪些场合下使用.事实上还是须要细致考虑的.我们当然不能为了使用而使用,而是须要找到切实实用的场合.在JDBC编程中,比如查询语句,首先须要进行 ...
- C++基础代码--20余种数据结构和算法的实现
C++基础代码--20余种数据结构和算法的实现 过年了,闲来无事,翻阅起以前写的代码,无意间找到了大学时写的一套C++工具集,主要是关于数据结构和算法.以及语言层面的工具类.过去好几年了,现在几乎已经 ...
- markdown模式的一些语法
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. 简书支持程序员写技术博客的模式,Markdown具有一系列衍生版本,用于扩展Mar ...
- Qt的paint函数重写,以及QPaint给一条线绘制箭头
直接代码: QPainter *painter; static const double Pi = 3.14159265358979323846264338327950288419717; stati ...
- 【u115】&&【t031】 01迷宫
01迷宫(maze01) Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相 ...
- Tomcat下部署SpringBoot
SpringBoot默认支持Tomcat7及以上版本(SpringBoot默认支持servlet3.1版本及以上,Tomcat6只支持到servlet2.5) 测试环境:jdk1.8 + tomcat ...
- Power control within a coherent multi-processing system
Within a multi-processing system including a plurality of processor cores 4, 6operating in accordanc ...
- Android分享介绍
一.使用系统分享 public void execShare(Activity context,String title,String text){ Intent intent = new Inten ...
- 不要完全相信Chrome控制台打印的信息
以下两张图,第一张是Chrome控制台Network里请求返回的信息,图二是在代码里在请求返回的处理第一行代码用console.log打印的信息. 图一 图二 那么问题来了,为何通过console.l ...