【发布时间】:2012-04-05 01:23:15
【问题描述】:
我想得到两张图片之间的区别
我使用这个源代码:
public Bitmap GetDifference(Bitmap bm1, Bitmap bm2)
{
if (bm1.Size != bm2.Size)
throw new ArgumentException("exception");
var resultImage = new Bitmap(bm1.Width, bm1.Height);
using (Graphics g = Graphics.FromImage(resultImage))
g.Clear(Color.Transparent);
for (int w = 0; w < bm1.Width; w++)
{
for (int h = 0; h < bm1.Height; h++)
{
var bm2Color = bm2.GetPixel(w, h);
if (IsColorsDifferent(bm1.GetPixel(w, h), bm2Color))
{
resultImage.SetPixel(w, h, bm2Color);
}
}
}
return resultImage;
}
bool IsColorsDifferent(Color c1, Color c2)
{
return c1 != c2;
}
这个来源对我很有效,但我有以下问题:
例如,如果我选择分辨率为 480x320 的图像,我的 resultImage 具有相同的分辨率(这是正确的,因为我在创建新位图时设置了),但我的图像具有透明颜色,我想获得结果图像仅限纯色。
让我们说 - 如果 480x320 中的纯色结果图像(纯色像素)具有 100x100 字段,我应该只获得分辨率为 100x100 的纯色位图。
简单地说,我只需要获得以纯色和 alpha chanel 为边界的矩形。
谢谢!
【问题讨论】:
-
当您遇到 alpha 通道 > 0 的像素时,您需要扫描图像并跟踪边界(假设您有矩形部分,这很容易)。还要注意
GetPixel和SetPixel像狗一样慢。真是一只慢热的狗。如果他们为您工作,并且您知道您的输入图像将始终非常小,那很好。如果图像的大小未知,我认为深入研究unsafe上下文并通过LockBits获取指向图像缓冲区的指针并不是过早的优化。 -
谢谢,是的,我知道。这将用于创建一个包,而不是在运行时使用(仅一次计算)
-
哦,又一个图像处理技巧;按行扫描图像,而不是像现在这样按列扫描。这里的假设是您的图像数据按行存储在数组中(这几乎总是正确的)。数据的局部性在这里很重要。您的代码目前可能不会导致 CPU 缓存中充满相邻数据。您将在每次迭代中刷新和填充缓存,这意味着从主内存中获取数据的行程更长。如果你按行循环它会。
-
@EdS。你能写下你的提示作为答案吗?它对其他人可能有用。谢谢
标签: c# image-processing bitmap