如何将System.Windows.Media.Imaging.BitmapImage转换为System.Drawing.Image?

时间:2012-03-07 08:27:02

标签: c# .net wpf

XAML:

<ImageBrush x:Key="Symbol1Brush" ImageSource="Resources\Symbol1.png" Stretch="Uniform" />

代码:

// In some class
_imageProcessor = new ImageProcessor(Resources["Symbol1Image"] as BitmapImage)

public class ImageProcessor
{
    private readonly Bitmap _primaryMarkerSymbol;

    public ImageProcessor(BitmapImage primaryMarkerSymbol)
    {
        if (primaryMarkerSymbol == null)
            throw new ArgumentNullException("primaryMarkerSymbol");

        _primaryMarkerSymbol = new Bitmap(primaryMarkerSymbol.StreamSource);
    }

    public Bitmap ProcessImage()
    {
        Graphics g = Graphics.FromImage(img);
        g.DrawImage(_primaryMarkerSymbol);
        g.Flush();

        return img;
    }
}

_primaryMarkerSymbol =新位图(primaryMarkerSymbol.StreamSource) 抛出异常:'null'的值对'stream'无效。

我假设如果从Resource。创建了BitmapImage,则不会填充StreamSource。

有哪些替代品? 感谢。

编辑:

重点是使用XAML ResourceDictionary中定义的源对象(例如ImageBrush,BitmapImage)。

4 个答案:

答案 0 :(得分:3)

您可能需要以某种方式复制位图的像素:

// test image
BitmapImage image = new BitmapImage(new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"));

// copy to byte array
int stride = image.PixelWidth * 4;
byte[] buffer = new byte[stride * image.PixelHeight];
image.CopyPixels(buffer, stride, 0);

// create bitmap
System.Drawing.Bitmap bitmap =
    new System.Drawing.Bitmap(
        image.PixelWidth,
        image.PixelHeight,
        System.Drawing.Imaging.PixelFormat.Format32bppArgb);

// lock bitmap data
System.Drawing.Imaging.BitmapData bitmapData =
    bitmap.LockBits(
        new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
        System.Drawing.Imaging.ImageLockMode.WriteOnly,
        bitmap.PixelFormat);

// copy byte array to bitmap data
System.Runtime.InteropServices.Marshal.Copy(
    buffer, 0, bitmapData.Scan0, buffer.Length);

// unlock
bitmap.UnlockBits(bitmapData);

答案 1 :(得分:1)

这对我来说可以使用资源文件设置图像源

var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
                                  IntPtr.Zero,
                                  Int32Rect.Empty,
                                  BitmapSizeOptions.FromEmptyOptions());
MyButton.Background = new ImageBrush(bitmapSource);

答案 2 :(得分:0)

在一个明确的时刻,我想出了一个我可以提供帮助的解决方案。

我使用BitmapImage.UriSource获取相对图像路径并加载图像:

public class ImageProcessor
{
    private readonly Image _primaryMarkerSymbol;

    public ImageProcessor(BitmapImage primaryMarkerSymbol)
    {
        _primaryMarkerSymbol = Image.FromFile(primaryMarkerSymbol.UriSource.ToString());
    }

    public Bitmap ProcessImage(string fileName)
    {
        var img = new Bitmap(fileName);
        Graphics g = Graphics.FromImage(img);
        g.DrawImage(_primaryMarkerSymbol);
        g.Flush();

        return img;
    }
}

如果我可以使用对象本身在图形上绘制图像而不是按路径加载,那将是一件好事。所以欢迎你提出一个更好的主意。

答案 3 :(得分:0)

在构造函数中,我宁愿使用它:


 record = {customerId: 1, activity: 'Activity1.1'}
db.tempc.update({_id: record.customerId}, {$push: {activities: record.activity}}, {upsert: true})