为了账号安全,请及时绑定邮箱和手机立即绑定

有没有一种在BitmapSource和Bitmap之间转换的好方法?

/ 猿问

有没有一种在BitmapSource和Bitmap之间转换的好方法?

暮色呼如 2019-11-15 10:56:59

据我所知,从BitmapSource转换为Bitmap的唯一方法是通过不安全的代码...像这样(来自Lesters WPF博客):


myBitmapSource.CopyPixels(bits, stride, 0);


unsafe

{

  fixed (byte* pBits = bits)

  {

      IntPtr ptr = new IntPtr(pBits);


      System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(

        width,

        height,

        stride,

        System.Drawing.Imaging.PixelFormat.Format32bppPArgb,ptr);


      return bitmap;

  }

}

要做相反的事情:


System.Windows.Media.Imaging.BitmapSource bitmapSource =

  System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(

    bitmap.GetHbitmap(),

    IntPtr.Zero,

    Int32Rect.Empty,

    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

框架中有没有更简单的方法?它不在其中的原因是什么(如果没有)?我认为这是相当有用的。


我需要它的原因是因为我使用AForge在WPF应用程序中执行某些图像操作。WPF希望显示BitmapSource / ImageSource,但AForge可以在Bitmap上使用。


查看完整描述

3 回答

?
翻过高山走不出你

通过使用Bitmap.LockBits像素并将像素从BitmapSource直线复制到像素,可以在不使用不安全代码的情况下进行操作Bitmap


Bitmap GetBitmap(BitmapSource source) {

  Bitmap bmp = new Bitmap(

    source.PixelWidth,

    source.PixelHeight,

    PixelFormat.Format32bppPArgb);

  BitmapData data = bmp.LockBits(

    new Rectangle(Point.Empty, bmp.Size),

    ImageLockMode.WriteOnly,

    PixelFormat.Format32bppPArgb);

  source.CopyPixels(

    Int32Rect.Empty,

    data.Scan0,

    data.Height * data.Stride,

    data.Stride);

  bmp.UnlockBits(data);

  return bmp;

}


查看完整回答
反对 回复 2019-11-15
?
慕婉清6462132

您可以使用以下两种方法:


public static BitmapSource ConvertBitmap(Bitmap source)

{

    return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(

                  source.GetHbitmap(),

                  IntPtr.Zero,

                  Int32Rect.Empty,

                  BitmapSizeOptions.FromEmptyOptions());

}


public static Bitmap BitmapFromSource(BitmapSource bitmapsource)

{

    Bitmap bitmap;

    using (var outStream = new MemoryStream())

    {

        BitmapEncoder enc = new BmpBitmapEncoder();

        enc.Frames.Add(BitmapFrame.Create(bitmapsource));

        enc.Save(outStream);

        bitmap = new Bitmap(outStream);

    }

    return bitmap;

}

它非常适合我。


查看完整回答
反对 回复 2019-11-15
?
湖上湖

这里的代码为资源词典中的任何位图资源(而不是Windows.Forms时代经常使用的Resources.resx)设置透明背景。我在InitializeComponent()-methode之前调用此方法。上面的melvas在文章中提到了方法'ConvertBitmap(Bitmap source)'和BitmapFromSource(BitmapSource bitmapsource)。


private void SetBitmapResourcesTransparent()

    {

        Image img;

        BitmapSource bmpSource;

        System.Drawing.Bitmap bmp;

        foreach (ResourceDictionary resdict in Application.Current.Resources.MergedDictionaries)

        {

            foreach (DictionaryEntry dictEntry in resdict)

            {

                // search for bitmap resource

                if ((img = dictEntry.Value as Image) is Image 

                    && (bmpSource = img.Source as BitmapSource) is BitmapSource

                    && (bmp = BitmapFromSource(bmpSource)) != null)

                {

                    // make bitmap transparent and assign it back to ressource

                    bmp.MakeTransparent(System.Drawing.Color.Magenta);

                    bmpSource = ConvertBitmap(bmp);

                    img.Source = bmpSource;

                }

            }


        }


    }


查看完整回答
反对 回复 2019-11-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信