将BitmapImage转换为Bitmap,反之亦然

时间:2011-06-26 13:50:46

标签: c# .net bitmap

我在C#中有BitmapImage。我需要对图像进行操作。例如灰度,在图像上添加文本等

我在stackoverflow中找到了grayscaling函数,它接受Bitmap并返回Bitmap。

所以我需要将BitmapImage转换为Bitmap,进行操作并转换回来。

我该怎么做?这是最好的方式吗?

8 个答案:

答案 0 :(得分:83)

无需使用外国图书馆。

将BitmapImage转换为位图:

private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
    // BitmapImage bitmapImage = new BitmapImage(new Uri("../Images/test.png", UriKind.Relative));

    using(MemoryStream outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapImage));
        enc.Save(outStream);
        System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);

        return new Bitmap(bitmap);
    }
}

将Bitmap转换回BitmapImage:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

private BitmapImage Bitmap2BitmapImage(Bitmap bitmap)
{
    IntPtr hBitmap = bitmap.GetHbitmap();
    BitmapImage retval;

    try
    {
        retval = (BitmapImage)Imaging.CreateBitmapSourceFromHBitmap(
                     hBitmap,
                     IntPtr.Zero,
                     Int32Rect.Empty,
                     BitmapSizeOptions.FromEmptyOptions());
    }
    finally
    {
        DeleteObject(hBitmap);
    }

    return retval;
}

答案 1 :(得分:38)

这是将Bitmap转换为BitmapImage的扩展方法。

    public static BitmapImage ToBitmapImage(this Bitmap bitmap)
    {
        using (var memory = new MemoryStream())
        {
            bitmap.Save(memory, ImageFormat.Png);
            memory.Position = 0;

            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = memory;
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();
            bitmapImage.Freeze();

            return bitmapImage;
        }
    }

答案 2 :(得分:7)

如果你只需要从BitmapImage转到Bitmap就很容易了,

java -Xss1G com.mypackage.Main

答案 3 :(得分:3)

使用System.Windows.Interop; ...

 private BitmapImage Bitmap2BitmapImage(Bitmap bitmap)
        {                
            BitmapSource i = Imaging.CreateBitmapSourceFromHBitmap(
                           bitmap.GetHbitmap(),
                           IntPtr.Zero,
                           Int32Rect.Empty,
                           BitmapSizeOptions.FromEmptyOptions());
            return (BitmapImage)i;
        }

答案 4 :(得分:2)

我刚刚尝试在我的代码中使用上面的内容,我相信Bitmap2BitmapImage函数存在问题(也可能是另一个函数)。

using (MemoryStream ms = new MemoryStream())

以上行是否导致流被处理?这意味着返回的BitmapImage会丢失其内容。

由于我是WPF新手,我不确定这是否是正确的技术解释,但在删除using指令之前,代码在我的应用程序中不起作用。

答案 5 :(得分:1)

这里是异步版本。

public static Task<BitmapSource> ToBitmapSourceAsync(this Bitmap bitmap)
{
    return Task.Run(() =>
    {
        using (System.IO.MemoryStream memory = new System.IO.MemoryStream())
        {
            bitmap.Save(memory, ImageFormat.Png);
            memory.Position = 0;
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = memory;
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();
            bitmapImage.Freeze();
            return bitmapImage as BitmapSource;
        }
    });

}

答案 6 :(得分:0)

这将从System.Drawing.Bitmap转换为BitmapImage:

MemoryStream ms = new MemoryStream();
YOURBITMAP.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();

答案 7 :(得分:0)

感谢Guillermo Hernandez,我创建了一个有效的代码变体。我在此代码中添加了名称空间以供参考。

System.Reflection.Assembly theAsm = Assembly.LoadFrom("My.dll");
// Get a stream to the embedded resource
System.IO.Stream stream = theAsm.GetManifestResourceStream(@"picture.png");

// Here is the most important part:
System.Windows.Media.Imaging.BitmapImage bmi = new BitmapImage();
bmi.BeginInit();
bmi.StreamSource = stream;
bmi.EndInit();