【问题标题】:Drawing on bitmap with shared source使用共享源绘制位图
【发布时间】:2015-02-02 16:25:52
【问题描述】:

我通过从另一个中提取 200x200 正方形来创建一个新的位图。我认为源(位图像素)由这两者共享。现在,当我在原始图像上画一个圆圈时,副本上也有一个。但是当我以另一种方式这样做时——在新创建的圆圈上画一个圆圈——原来的圆圈上没有圆圈。为什么会这样?我以为源像素是共享的。

    private Bitmap testa(Bitmap bmp)
    {
        System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);

        //Create a new bitmap.
        Bitmap newBitmap = new Bitmap(200, 200, bmpData.Stride, bmp.PixelFormat, bmpData.Scan0);

        bmp.UnlockBits(bmpData);

        // Draw the new bitmap.
        using (Graphics g = Graphics.FromImage(bmp)) // or: newBitmap
        {
            g.DrawEllipse(new Pen(Brushes.Red), 1, 1, 100, 100);
        }
        return newBitmap;
    }

【问题讨论】:

  • 我认为您实际上并没有“共享”像素。你只复制它们有或没有圆圈。另外:为什么不使用 DrawImage 进行复制?它有一种格式可以做到这一点!
  • @TaW 那么为什么当我先复制图像然后在上面绘制时,两个图像上都会显示圆圈?对于 DrawImage:这只是一个示例,我只有 IntPtr 可以从不整个 Bitmap 复制。
  • 我们看到代码了吗?

标签: c# bitmap drawing share pixel


【解决方案1】:

基本上,您错误地使用了LockBits()Bitmap() 构造函数,因此无论您看到什么行为,这纯粹是学术性的和不确定的。

您传递给Bitmap(int, int, int, PixelFormat, IntPtr) 构造函数的IntPtr 必须是您为该特定位图分配的一个。您需要确保it remains valid for the lifetime of the Bitmap object

另一方面,BitmapData.Scan0 指针保证仅在您调用UnlockBits() 之前保持有效。到那时,它可能会也可能不会。

如果你好奇,尝试其他实验可能会很有趣,比如在原始位图上绘制,查看新位图,然后在新位图上绘制,查看原始位图,最后再次在原始位图上绘制并查看新的。

但是,无论您在此类实验中发现什么行为,您都不能依赖它,因为该行为没有记录在案且不受支持。据我所知,没有支持的机制允许两个不同的Bitmap 对象共享同一个缓冲区。它似乎在某些孤立的情况下有效,这纯粹是运气。

【讨论】:

  • 我没有阅读链接页面中的备注部分,但我的示例也来自那里。这说明了很多。谢谢
  • 对于从 IntPtr 复制位图有什么建议?我应该像这样创建 tmp Bitmap 然后 Clone() 它吗?
  • 个人?除非您对速度的重视程度远远 高于便利性,否则我根本不会与LockBits() 混淆。要精确复制位图,只需使用Bitmap(Image) 构造函数。如果要裁剪位图,请创建所需大小的新Bitmap 对象,调用Graphics.FromImage(Image) 传递新位图,然后使用@987654334 将您想要的原始位图部分绘制到新位图中@方法。
  • 如果您需要速度,您可以使用LockBits(),但即便如此,我也会让 GDI+ 为您分配缓冲区。创建所需大小的新空位图,在原始位图和新位图上调用 LockBits(),然后将字节从一个缓冲区复制到另一个缓冲区(例如使用 Marshal.Copy())。
猜你喜欢
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多