如何创建位图深拷贝

发布于 2024-11-05 10:34:56 字数 782 浏览 3 评论 0原文

我正在应用程序中处理位图,出于某些目的,我需要创建位图的深层副本。有没有一种优雅的方法来做到这一点?

我尝试过

Bitmap deepCopy = original.Clone();

,显然这不会创建深层副本,而是创建浅层副本。 我的下一次尝试是创建一个新的位图,

Bitmap deepCopy = new Bitmap(original);

不幸的是这个构造函数是位图(图像),而不是位图(位图),位图(图像)会将我漂亮的 8bppIndexed Pixelformat 转换为不同的格式。

另一种尝试是使用 MemoryStream

public static Bitmap CreateBitmapDeepCopy(Bitmap source)
{
    Bitmap result;
    using (MemoryStream stream = new MemoryStream())
    {
        source.Save(stream, ImageFormat.Bmp);
        stream.Seek(0, SeekOrigin.Begin);
        result = new Bitmap(stream);
    }
    return result;
}

好吧,这也不起作用,因为必须在 Bitmap 的整个生命周期内打开 MemoryStream。

所以,我总结了所有的死胡同,我真的很想看到一种创建位图深层副本的优雅方式。谢谢你:)

I'm dealing with Bitmaps in my application and for some purposes I need to create a deep copy of the Bitmap. Is there an elegant way how to do it?

I tried

Bitmap deepCopy = original.Clone();

,well apparently this doesn't create a deep copy, but shallow one.
My next attempt was to create a new Bitmap

Bitmap deepCopy = new Bitmap(original);

Unfortunately this constructor is Bitmap(Image), not Bitmap(Bitmap) and Bitmap(Image) will convert my nice 8bppIndexed Pixelformat into a different one.

Another attempt was to use of a MemoryStream

public static Bitmap CreateBitmapDeepCopy(Bitmap source)
{
    Bitmap result;
    using (MemoryStream stream = new MemoryStream())
    {
        source.Save(stream, ImageFormat.Bmp);
        stream.Seek(0, SeekOrigin.Begin);
        result = new Bitmap(stream);
    }
    return result;
}

Well, this doesn't work either, since the MemoryStream has to be opened during the whole lifetime of Bitmap.

So, I've summed up all my deadends and I'd really like to see a nice elegant way of creating a Bitmap deep copy. Thanks for that :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

烟凡古楼 2024-11-12 10:34:56
B.Clone(new Rectangle(0, 0, B.Width, B.Height), B.PixelFormat)
B.Clone(new Rectangle(0, 0, B.Width, B.Height), B.PixelFormat)
找个人就嫁了吧 2024-11-12 10:34:56

我偶然发现的另一种实现相同效果的方法是旋转或翻转图像。在幕后似乎创建了位图的全新副本。进行两次旋转或翻转可以让您最终获得原始图像的精确副本。

result.RotateFlip(RotateFlipType.Rotate180FlipX);
result.RotateFlip(RotateFlipType.Rotate180FlipX);

Another way I stumbled on that achieves the same thing is to rotate or flip the image. Under the hood that seems to create a completely new copy of the bitmap. Doing two rotations or flips lets you end up with an exact copy of the original image.

result.RotateFlip(RotateFlipType.Rotate180FlipX);
result.RotateFlip(RotateFlipType.Rotate180FlipX);
不如归去 2024-11-12 10:34:56

我的环境:Windows 10、Visual Studio 2015、Framework 4.5.2

它适合我。

Bitmap deepCopy = new Bitmap(original);

My environment:Windows 10, Visual Studio 2015, Framework 4.5.2

It works for me.

Bitmap deepCopy = new Bitmap(original);
jJeQQOZ5 2024-11-12 10:34:56

您可以序列化位图,然后反序列化它。位图是可序列化的。

You could serialize the bitmap and then deserialize it. Bitmap is serializable.

听闻余生 2024-11-12 10:34:56

您可以将以下类放入代码中:

public static class BitmapExtensions
{
    public static Bitmap DeepClone(this Bitmap source)
    {
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new MemoryStream();
        using (stream)
        {
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);
            return (Bitmap)formatter.Deserialize(stream);
        }
    }
}

此方法经过调整以与 Bitmap 一起使用。如果您想使用通用方法,请查看下面的链接。通过命名方法 DeepClone(),我们消除了破坏现有代码的风险(在下面的答案中,该方法称为 Clone(),因此它是一个重写方法)。

原文来自这里: https://stackoverflow.com/a/43042865/13574233

不过,这种方法需要很多时间。如果您正在寻找一种良好的执行方法,那么这可能不是您想要的。

You can place the following class in your code:

public static class BitmapExtensions
{
    public static Bitmap DeepClone(this Bitmap source)
    {
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new MemoryStream();
        using (stream)
        {
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);
            return (Bitmap)formatter.Deserialize(stream);
        }
    }
}

This method is adjusted to work with Bitmap. If you want to have a generic method look into the link below. By naming the method DeepClone() we remove the risk of breaking already existing code (in the answer below the method is called Clone(), so it's a override method).

Original from here: https://stackoverflow.com/a/43042865/13574233

This method takes a lot of time though. If you're looking for a good performing method, this probably isn't what you're looking for.

北城孤痞 2024-11-12 10:34:56

假设您已经有一个名为“原始”的位图,其中包含一些内容,

Bitmap original = new Bitmap( 200, 200 );     
Bitmap copy = new Bitmap(original.Width, original.Height);
using (Graphics graphics = Graphics.FromImage(copy))
{
  Rectangle imageRectangle = new Rectangle(0, 0, copy.Width, copy.Height);
  graphics.DrawImage( original, imageRectangle, imageRectangle, GraphicsUnit.Pixel);
}

这应该创建一个相同大小的副本,并将原始位图绘制到副本中。

Suppose you already have a bitmap called original with something in it

Bitmap original = new Bitmap( 200, 200 );     
Bitmap copy = new Bitmap(original.Width, original.Height);
using (Graphics graphics = Graphics.FromImage(copy))
{
  Rectangle imageRectangle = new Rectangle(0, 0, copy.Width, copy.Height);
  graphics.DrawImage( original, imageRectangle, imageRectangle, GraphicsUnit.Pixel);
}

This should create a copy of the same size, and draw the original into the copy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文