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 ...
随机推荐
- Android的NDK开发(5)————Android JNI层实现文件的read、write与seek操作
1. 在Android的Java层实现文件的读写操作是非常简单的,可以参看之前写的博文:http://blog.csdn.net/conowen/article/details/7296121 在JN ...
- 通过binlog日志统计dml语句,找出操作频繁的表
mysqlbinlog --no-defaults --base64-output=decode-rows -v -v mysql-bin.000002 |awk '/###/{if($0~/UPDA ...
- 学习鸟哥的Linux私房菜笔记(11)——系统监视1
一.了解系统状况 uname:显示系统信息 hostname:显示主机名 last:列出最近的用户登录 lastlog:列出每一个用户的最近登录情况 free:显示内存使用状况 还可以使用vmstat ...
- oracle数据库零散知识01
1,rownum 是一个虚列,使用时必须包括1才能使用,rownum = 1,rownum < 10; rownum = 2是不可以的: 2,if case loop 要加end结束,end ...
- web IDE Eclipse Che安装
安装:使用安装器安装 使用安装器安装Che 环境 依赖 下载地址 通用 任何操作系统,java8,Git,Maven 3.0.5+,Docker 1.7+ 3.12.52 - 117MB window ...
- 怎样获取android手机联系人并按字母展示(三)
假设获取contact的头像信息并展示: 怎样依据photoId来获取bitmap: public static Bitmap getContactPhoto(Context context, lon ...
- VS Code插件之Cordova Tools
原文:VS Code插件之Cordova Tools 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011127019/article/detai ...
- 【28.57%】【codeforces 711E】ZS and The Birthday Paradox
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- sql这两个表和查询的组合yii通过使用数据库查询
sql两个表的组合查询 使用 join on 比如:两个表查询: select u.username, t.title from user u join task t on u.id = t.id; ...
- C#--动态操作DataTable
C#动态操作DataTable(新增行.列.查询行.列等) 方法一:动态创建一个DataTable ,并为其添加数据 public void CreateTable() { ...