这个方法有几个前提

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. 【hdu5692】Snacks

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submissio ...

  2. AE属性表操作

    转自chanyinhelv原文AE属性表操作 实现的操作包括:1.打开属性表:2.编辑属性表:3.增加属性列:4.数据排序:5.字段计算…… 嗯,实现的功能目前就这些吧,后续还会继续跟进,还望大家多多 ...

  3. 温故而知新-String类

    String不算是一种类型,而算是一个类.就是说String不仅能够表示string类型,另一些自带的方法能够调用.温故而知新.如今给大家总结了String类应该注意的地方. (1)"==& ...

  4. 跟上 Java 8 – 了解 lambda

    原文出处: 王爵nice 从java8出现以来lambda是最重要的特性之一,它可以让我们用简洁流畅的代码完成一个功能. 很长一段时间java被吐槽是冗余和缺乏函数式编程能力的语言,随着函数式编程的流 ...

  5. lucene 统计单词次数(词频tf)并进行排序

    public class WordCount { static Directory directory; // 创建分词器 static Analyzer analyzer = new IKAnaly ...

  6. 构建工具Gradle

    1.Summary   从Android团队开始宣布放弃Eclipse转投Android Studio时,构建工具Gradle进入了Android开发者的视野.而随着热修复.插件化.编译时注解的流行, ...

  7. Redux中reducer的翻译

    reduce有归纳,简化的意思,所以reducer可翻译成归并函数的意思,其实没必要翻译,大体知道就可以了.

  8. Redmine迁移至华为软件开发云-项目管理

    一.方案概述 要想将Redmine中某个项目的数据导入到华为软件开发云(以下简称开发云),如果说是按照Redmine中的数据一条一条的在开发云中新建出来,肯定不是一个明智的方案,下面就是给大家介绍一个 ...

  9. 从华为产品学到什么是devops

    根据Gartner 2015 I&O Automation 报告,DevOps处于技术发展的最高点,实践受到高度关注,到底devops魔力在哪里? 从devops实践看主要是打破开发人员和运营 ...

  10. Android 它们的定义View

    安卓开发过程,安卓官方控制有时来自往往不能满足我们的需求.这一次,我必须定义自己.下面我们就来看看他们的定义View: package com.example.myview; import andro ...