【问题标题】:System.Drawing and WPF Interop - CreateBitmapSourceFromHBitmapSystem.Drawing 和 WPF 互操作 - CreateBitmapSourceFromHBitmap
【发布时间】:2011-07-05 19:17:58
【问题描述】:

我在 system.drawing 和 WPF 之间进行互操作时遇到问题。为了简化这个问题,我建立了一个例子来说明这个问题。我使用 System.Drawing 进行绘制,然后使用 CreateBitmapSourceFromHBitmap 将结果复制到 System.Windows.Controls.Image。正如您在屏幕截图中看到的那样,不知何故,alpha 信息丢失了。

在透明的位图上绘制黑色文本,然后复制到本身透明的图像组件中。父网格本身具有黑色背景。我猜结果是一个完全黑色的图像,但事实并非如此,在进行抗锯齿时,文本似乎是使用白色作为背景绘制的。

Link to Screenshot

这是 MainWindow.xaml 的代码:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Name="grid" Background="Black">
        <Image Name="image" Stretch="Fill" Loaded="image_Loaded"></Image>
    </Grid>
</Window>

还有 MainWindow.xaml.cs 的代码:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void image_Loaded(object sender, RoutedEventArgs e)
        {
            //use system drawing to draw text
            Bitmap bmp = new Bitmap ( (Int32) grid.ActualWidth, (Int32) grid.ActualHeight );
            Graphics graphics = Graphics.FromImage ( bmp );

            var brush = new SolidBrush(Color.FromArgb(255, 0, 0, 0));
            var font = new Font(System.Drawing.FontFamily.GenericSansSerif, 30.0f, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel);

            graphics.Clear(Color.Transparent);
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.CompositingMode = CompositingMode.SourceOver;
            graphics.CompositingQuality = CompositingQuality.HighQuality;

            //draw text
            graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            graphics.TextContrast = 5;
            graphics.DrawString("My Text", font, brush, 10, 10);

            //try saving
            bmp.Save("E:\\temp.png", System.Drawing.Imaging.ImageFormat.Png);

            //back to wpf image control
            image.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap ( bmp.GetHbitmap ( ), IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight ( (Int32) grid.ActualWidth, (Int32) grid.ActualHeight ) );
        }
    }
}

有人经历过吗?怎样才能获得不预乘白色的平滑抗锯齿效果?

【问题讨论】:

    标签: c# wpf interop system.drawing


    【解决方案1】:

    不是最迷人的解决方案,但我可以让它正常工作的唯一方法是使用 Save() 函数保存位图,然后对其进行解码并将其作为 BitmapSource 加载:

         bmp.Save("E:\\temp.png", System.Drawing.Imaging.ImageFormat.Png);
         //A neater way to free up the file!
         bmp.Dispose();
         bmp = null;
         //Load up the image.
         BitmapFrame frm = new BitmapFrame(new Uri("E:\\temp.png"));
         image.Source = frm as BitmapSource;
    

    现在这不是最巧妙的解决方案,但这是我能遇到的全部。

    【讨论】:

    • 你不需要这个肮脏的黑客来释放文件......保存完成后会关闭文件。无论如何,你总是可以显式调用 bmp.Dispose
    • 是的,我想是的——当时没有想到这一点。我会修正我的答案并整理出来以避免混淆。
    • 为什么不使用MemoryStream 而不是文件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    相关资源
    最近更新 更多