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开发(3)————JNI数据类型的详解
在Java中有两类数据类型:primitive types,如,int, float, char:另一种为reference types,如,类,实例,数组. 注意:数组,不管是对象数组还是基本类型数 ...
- Fragment使用LocalBroadcastManager接收广播消息
这种方式不用在配置文件加东西 变量声明 LocalBroadcastManager broadcastManager; IntentFilter intentFilter; BroadcastRece ...
- C++省略号类型和参数个数不确定函数参数范例
声明:所有权利保留. 转载必须说明出处:http://blog.csdn.net/cartzhang/article/details/44203651 今天想写个宏定义,发现宏定义里也可以写不定参数, ...
- java nio 缓冲区(一)
本文来自于我的个人博客:java nio 缓冲区(一) 我们以Buffer类開始对java.nio包的浏览历程.这些类是java.nio的构造基础. 这个系列中,我们将尾随<java NIO ...
- Vagi单点登录1.0
Vagi是一款基于CAS(CAS v4)的Web应用单点登录系统.(cas web https://github.com/Jasig/cas) 对数据库用户存储支持 加入登录验证码 新浪微博和QQ互联 ...
- WPF应用最小化至系统托盘运行
原文:WPF应用最小化至系统托盘运行 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lordwish/article/details/5178889 ...
- python 多进程与多线程配合拷贝文件目录
版本一:使用shutil进行拷贝 # -*- coding: utf-8 -*- # @author: Tele # @Time : 2019/04/02 下午 3:09 # 待改进: # 1.拷贝逻 ...
- css+html+js实现多级下拉和弹出菜单
本文将使用css+html+js实现横向菜单.具有多级弹出菜单下拉. 首先我们来看看效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgy ...
- 如何在使Xcode打包iOS应用时自动增加编译号
在红框标注的输入框中输入:真机调试编译成功增加 echo $CONFIGURATION if [ "Release" == "${CONFIGURATION}" ...
- [02]基于webservice权限系统
面前,我们已经介绍过.如何使用cxf建立webservice. 那我们要介绍的这款许可制度表结构. 此权限管理系统分为部门管理.员工管理.角色管理,权限管理,授权的人才和企业管理(这里不涉及) 角色管 ...