【问题标题】:Need help for merging one image with another image需要帮助将一张图片与另一张图片合并
【发布时间】:2013-05-15 14:29:38
【问题描述】:

假设我以编程方式比较两个图像。提取两个图像之间的差异后,假设我将差异存储在另一个名为 bmp3

的位图变量中

我从另一个站点获得了一个代码,该代码显示了如何将差异与第一张图像合并。

假设我有两个名为 bmp1 和 bmp2 的位图变量。我以编程方式提取两个名为 bmp1 & bmp2 的变量之间的差异,并将其存储在 bmp3 变量中。

现在我想将差异与 bmp1 变量合并在同一位置。因此,我从一个站点获得了代码,并且运行良好,但是我对该代码的几行感到困惑。

代码如下:

Bitmap bComb = new Bitmap(bmp3.Width, bmp3.Height);

using (Graphics g = Graphics.FromImage(bComb))
{
    g.DrawImage(this.pictureBox1.Image, 0, 0, bComb.Width, bComb.Height);
    g.DrawImage(bmp3, 0, 0, bComb.Width, bComb.Height);
}

this.pictureBox4.Image = bComb;

这行的意思是

Bitmap bComb = new Bitmap(bmp3.Width, bmp3.Height);

bcom 是新变量,它的大小与 bmp3 相同......我说的对吗?

这一行的含义 g.DrawImage(this.pictureBox1.Image, 0, 0, bComb.Width, bComb.Height); ?

我们正在将 picbox1 内容从 0,0 坐标写入 bcom 变量....我说的对吗?

我们再次将 bmp3 内容从 0,0 坐标写入 bcom 变量....我说的对吗?

最后一行让我感到困惑。为什么我们再次将 bmp3 变量内容从 0,0 坐标写入 bcom 变量....我说的对吗?

如果我们再次从 0,0 坐标将两者写入 bcom 变量,那么 pic 应该彼此重叠,但输出正确。这是怎么可能的。

我需要你的帮助来理解这几行。所以请详细讨论这些线以及为什么总是使用 0,0 坐标。请帮助我理解代码。谢谢

【问题讨论】:

    标签: c# gdi image-comparison


    【解决方案1】:

    1. bComb is new variable which will have same size of bmp3 ....... am i right ?

    是的,它是一个大小为bmp3 的位图,我们将用它在上面绘制一些其他东西,但现在它只包含空像素,仅此而已!

    2.

    using (Graphics g = Graphics.FromImage(bComb))
    

    这条线让我们能够在bComb 上绘制我们需要的任何东西,它可以是位图、矩形或任何东西!

    3.

    g.DrawImage(this.pictureBox1.Image, 0, 0, bComb.Width, bComb.Height);
    

    在这里它将this.pictureBox1.Image 绘制到从点(0,0)(bComb.Width,bComb.Height) 的位图(bComb),这将包含整个位图

    4.

    g.DrawImage(bmp3, 0, 0, bComb.Width, bComb.Height);
    

    bmp3 再次从(0,0) 点被吸引到bComb(bComb.Width,bComb.Height)

    位图从同一点以相同的大小相互绘制,关键是如果它们包含透明像素,结果将是这些位图的组合,否则您只会看到bmp3稍后绘制并且没有第一张图像的线索,我们使用 (0,0) 因为它是我们位图的起点,我们可以使用任何其他点来绘制我们的东西,但是这样我们会留下一些像素,所以我们为什么要? :)

    • 更新:完全有可能将图像相互绘制,如果它们具有透明像素,结果将类似于 marge ,但正如您所提到的,如果最后一个位图不包含任何透明像素,那么我们将看到的唯一图片是最后一张,我们将无法看到以前的位图,因为这些像素被最后一个位图覆盖了随意使用一些 png 半透明图像并将它们绘制在上面彼此顶部并查看结果,恐怕我不知道任何用于图像比较的内置 gdi+ 功能,但您可以通过 gdi+ 中的GetPixel() 函数轻松完成,并将一个位图中的每个像素与另一个,或者您可以使用不安全的代码并直接访问内存,这完全取决于您,但如果您想要一个干净简单的方法,请使用GetPixel()!你也可以看看英特尔的open-cv 图像处理库,希望对您有所帮助

    【讨论】:

    • 你解释得很好,但第 3,4 点不清楚。很明显,代码在 bcom 变量上绘制图像。第一次从 0,0 坐标绘制很清楚,但下一行从 0,0 再次绘制图像?如果我们在另一个图像上绘制一个图像,那么第一个应该被隐藏,但在我的情况下输出是正确的。
    • 我猜 image1 和 diff 图像具有相同的宽度,而 diff 图像有很多透明像素。如果是这种情况,则可以一个接一个地写入两个图像,然后合并图像看起来像第一个图像。我说的对吗?
    • dot 有任何内置的 gdi 功能可以告诉我两个图像是否相同?也应该先例行公事。请指导。
    • 我添加了更多信息,希望对您有所帮助,如果对答案有任何困惑,请再次告诉我:)
    【解决方案2】:

    Bitmap bComb = new Bitmap(bmp3.Width, bmp3.Height); 这里我们创建一个与 bm3 大小相同的空图像(bComb)。

    using (Graphics g = Graphics.FromImage(bComb)) 这将创建一个新图形,它将使用空图像 bComb。任何用图形绘制的东西,都会直接应用到 bComb 上。

    g.DrawImage(this.pictureBox1.Image, 0, 0, bComb.Width, bComb.Height); 这会将图片从图片框绘制到 bComb 上,并将其拉伸以匹配图像大小。

    g.DrawImage(bmp3, 0, 0, bComb.Width, bComb.Height); 这会将 bm3 绘制到 bComb 上,位于我们之前绘制的图片框图像之上。这看起来像什么,取决于该图像是否具有透明度。假设我们看起来是正确的,这可能意味着 bm3 有一个 alpha 值(透明度),因此它将作为前一张图像的一种过滤器,结果似乎是两者的合并。

    编辑:此外,您可能想要查看一些库:Accord.Net(这是Aforge.Net 的扩展。这两者的组合几乎涵盖了您需要的任何图像过滤器、比较或效果。另一个不错的是EMGU CV,它是另一个答案中提到的 OpenCV 库的 C# 包装器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-04
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多