这个方法有几个前提

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图片是否碰撞的更多相关文章

  1. WPF判断两个时间大小避免误差

    进行查询操作的时候,经常用到判断开始时间和结束时间大小的条件,由于从控件上获取的时间除了年月日时分秒,还包括毫秒.微秒等,导致直接判断时间大小的时候会产生一些误差,如下: 结果分析:年月日时分秒一致的 ...

  2. WPF 下两种图片合成或加水印的方式(转载)

    来源:http://www.cnblogs.com/lxblog/ 最近项目中应用多次应用了图片合成,为了今后方便特此记下. 在WPF下有两种图片合成的方式,一种还是用原来C#提供的GDI+方式,命名 ...

  3. Java 判断两个对象是否相等

    一.使用 == 与 equals == : 它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不是同一个对象.(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) equals() ...

  4. 如何判断单链表是否存在环 & 判断两链表是否相交

    给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针sl ...

  5. WPF 通过位处理合并图片

    原文:WPF 通过位处理合并图片 本文告诉大家,在使用 WPF 合并两张图片的处理,可以使用像素之间的与或和异或的方式,对三个颜色的通道进行处理. 先给大家看一下软件的界面 这就是通过将左边的两张图片 ...

  6. WPF 判断调用方法堆栈

    原文:WPF 判断调用方法堆栈 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客 ...

  7. WPF和Winform中picturebox图片局部放大

    原文:WPF和Winform中picturebox图片局部放大 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/artic ...

  8. java判断文件是否为图片

    /** * 判断文件是否为图片<br> * <br> * @param pInput 文件名<br> * @param pImgeFlag 判断具体文件类型< ...

  9. 2019-7-22-WPF-如何判断两个-LinearGradientBrush-相等

    title author date CreateTime categories WPF 如何判断两个 LinearGradientBrush 相等 lindexi 2019-07-22 21:26:2 ...

随机推荐

  1. 散列:散列函数与散列表(hash table)

    1. 散列函数 如果输入的关键字是整数,则一般合理方法是直接返回对表大小取模(Key mod TableSize)的结果,除非 Key 碰巧具有一些不太理想的特质.如,表的大小为 10,而关键字都是 ...

  2. java 原子量Atomic举例(AtomicReference)

    java并发库提供了很多原子类来支持并发访问的数据安全性,除了常用的 AtomicInteger.AtomicBoolean.AtomicLong 外还有 AtomicReference 用以支持对象 ...

  3. hdu 4059 The Boss on Mars

    The Boss on Mars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. shell配置java环境变量和批处理配置环境变量

    linux配置java环境只需在/etc/profile中添加以下 前提是把jdk解压到/usr/local路径,当然路径可以随便改 export JAVA_HOME=/usr/local/jdk1. ...

  5. 【9210】找礼物(char* num[2000]的使用 get char num[i] = new char[1000])

    Time Limit: 10 second Memory Limit: 2 MB 问题描述 新年到了,突然间,就在那美丽的一霎那,你好友和你(K个人)的周围满是礼物,你发扬你帅气的风格,让你的好友先拿 ...

  6. WPF 在image控件用鼠标拖拽出矩形

    原文:WPF 在image控件用鼠标拖拽出矩形 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee ...

  7. SQL Server 统计某个月周末的天数

    ---注意:这里统计的周末包括周5,周6,但不包括周日ALTER FUNCTION [dbo].[GetWeekDaysByMonth] ( @Year INT, @Month INT, @Day I ...

  8. 计时器timer的使用

    https://www.cnblogs.com/ILoveSleep/archive/2013/06/12/3133322.html

  9. Method and system for public-key-based secure authentication to distributed legacy applications

    A method, a system, an apparatus, and a computer program product are presented for an authentication ...

  10. 如何停止处于stopping状态的windows服务(使用taskkill)

    工作中有时需要启动和停止windows service,有时候会出现服务处于stopping或者starting的状态,但是,在services界面中,start service/stop servi ...