System.Drawing and WPF Interop - CreateBitmapSourceFromHBitmap
I have a problem interoperating between system.drawing and WPF. To simplify this question I've build an example to illustrate the problem. I draw using System.Drawing and then I copy the result to the System.Windows.Controls.Image using CreateBitmapSourceFromHBitmap. And somehow the alpha information is lost as you can see in the screenshot.
Black text is drawn on the transparent Bitmap and then copied to the image component which is transparent itself. The parent grid itself has a black background. I would guess that the result is a completely black image, but it is not, the text seems to be drawn using white as background when doing the anti-aliasing.
Link to Screenshot
Here's the code for 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>
And the code for 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 contro开发者_高级运维l
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 ) );
}
}
}
Does anyone have experienced this? How can I have a smooth anti-aliasing effect which is not pre-multiplied with white?
Not the most glamorous solution, but the only way I can get it to work properly is by saving the bitmap with the Save() function and then decoding it and loading it as a 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;
Now that's not the neatest solution, but it's all I can come across.
精彩评论