C# - 将 WPF Image.source 转换为 System.Drawing.Bitmap

标签 c# image image-processing bitmap

我发现很多人将 BitmapSource 转换为 Bitmap,但是将 ImageSource 转换为 Bitmap?我正在制作一个成像程序,我需要从 Image 元素中显示的图像中提取位图。有谁知道如何做到这一点?

编辑 1:

这是一个将BitmapImage 转换为Bitmap 的函数。请记住在编译器首选项中设置“不安全”选项。

public static System.Drawing.Bitmap BitmapSourceToBitmap(BitmapSource srs)
{
    System.Drawing.Bitmap btm = null;

    int width = srs.PixelWidth;

    int height = srs.PixelHeight;

    int stride = width * ((srs.Format.BitsPerPixel + 7) / 8);

    byte[] bits = new byte[height * stride];

    srs.CopyPixels(bits, stride, 0);

    unsafe
    {
        fixed (byte* pB = bits)
        {
            IntPtr ptr = new IntPtr(pB);

            btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr);
        }
    }
    return btm;
}

下一步是获取BitmapImage:

RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
    (int)inkCanvas1.ActualWidth,
    (int)inkCanvas1.ActualHeight,
    96d, 96d,
    PixelFormats.Default);

targetBitmap.Render(inkCanvas1);

MemoryStream mse = new MemoryStream();
System.Windows.Media.Imaging.BmpBitmapEncoder mem = new BmpBitmapEncoder();
mem.Frames.Add(BitmapFrame.Create(targetBitmap));
mem.Save(mse);

mse.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = mse;
bi.EndInit();

接下来是转换它:

Bitmap b = new Bitmap(BitmapSourceToBitmap(bi));

最佳答案

实际上你不需要使用不安全的代码。有一个接受 IntPtr 的 CopyPixels 的重载:

public static System.Drawing.Bitmap BitmapSourceToBitmap2(BitmapSource srs)
{
    int width = srs.PixelWidth;
    int height = srs.PixelHeight;
    int stride = width * ((srs.Format.BitsPerPixel + 7) / 8);
    IntPtr ptr = IntPtr.Zero;
    try
    {
        ptr = Marshal.AllocHGlobal(height * stride);
        srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height * stride, stride);
        using (var btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr))
        {
            // Clone the bitmap so that we can dispose it and
            // release the unmanaged memory at ptr
            return new System.Drawing.Bitmap(btm);
        }
    }
    finally
    {
        if (ptr != IntPtr.Zero)
            Marshal.FreeHGlobal(ptr);
    }
}

关于C# - 将 WPF Image.source 转换为 System.Drawing.Bitmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5689674/

相关文章:

列表列表中字符串的唯一记录的 C# Lambda 表达式

c++ - 如何在 Jasper JPEG2000 中指定小端

html - 上传的图片在网站上出现旋转

android - 相机像素旋转

c++ - Opencv 2.4 snakeImage C++

c# - 使用 Linq 查询连接两个字段

c# - DataGridView 的绑定(bind)表仅在双击时生成一个 RowChanged 事件。我如何让它做两个?

c# - 将 MouseEnter/MouseLeave 事件与 ContextMenus 一起使用

java - 为什么这不显示我的背景图片 title.png?

c - 通常使用大小为 4 的未初始化值