Боюсь, что ваш код не может работать. Действительно, вы копируете пустой образ в Graphics
, а затем сохраняете это изображение в файл. Таким образом, файл пуст.
Если вы не хотите использовать RenderTargetBitmap, вам необходимо использовать функцию BitBlt.
Давайте посмотрим, как это сделать. Прежде всего давайте создадим вспомогательный класс, который управляет преобразованием из Визуальных в Bitmap:
public static class VisualToBitmapConverter
{
private enum TernaryRasterOperations : uint
{
SRCCOPY = 0x00CC0020,
SRCPAINT = 0x00EE0086,
SRCAND = 0x008800C6,
SRCINVERT = 0x00660046,
SRCERASE = 0x00440328,
NOTSRCCOPY = 0x00330008,
NOTSRCERASE = 0x001100A6,
MERGECOPY = 0x00C000CA,
MERGEPAINT = 0x00BB0226,
PATCOPY = 0x00F00021,
PATPAINT = 0x00FB0A09,
PATINVERT = 0x005A0049,
DSTINVERT = 0x00550009,
BLACKNESS = 0x00000042,
WHITENESS = 0x00FF0062,
CAPTUREBLT = 0x40000000
}
[DllImport("gdi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
public static Bitmap GetBitmap(Visual visual, int width, int height)
{
IntPtr source;
IntPtr destination;
Bitmap bitmap = new Bitmap(width, height);
HwndSource hwndSource = (HwndSource)PresentationSource.FromVisual(visual);
using (Graphics graphicsFromVisual = Graphics.FromHwnd(hwndSource.Handle))
{
using (Graphics graphicsFromImage = Graphics.FromImage(bitmap))
{
source = graphicsFromVisual.GetHdc();
destination = graphicsFromImage.GetHdc();
BitBlt(destination, 0, 0, bitmap.Width, bitmap.Height, source, 0, 0, TernaryRasterOperations.SRCCOPY);
graphicsFromVisual.ReleaseHdc(source);
graphicsFromImage.ReleaseHdc(destination);
}
}
return bitmap;
}
}
Теперь мы можем написать простой XAML только для тестирования вспомогательного класса:
<Window x:Class="WpfApplication1.MainWindow" Name="win"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="400">
<StackPanel>
<Border BorderBrush="DarkGray" BorderThickness="4" CornerRadius="4"
Background="LightGray" Padding="6" Name="border">
<Label Content="Copy me to a bitmap file, please" FontSize="20" Foreground="Green"
FontStyle="Italic" />
</Border>
<Button Content="Save to file" Margin="20" HorizontalAlignment="Center"
Click="Button_Click" />
</StackPanel>
</Window>
С его фонового кодом :
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Bitmap image = VisualToBitmapConverter.GetBitmap(border,
(int)border.ActualWidth, (int)border.ActualHeight);
image.Save(@"C:\YourPath\test.png");
}
}
}
Если вы нажмете кнопку, вы найдете Границу и ее содержимое скопировано в файл растрового изображения. Я надеюсь, что скорость этого метода подходит для вашей наживки.
Что не работает? Вы получаете ошибку, вы получаете неправильные результаты, все еще не счастливы с производительностью ... – sous2817
Ошибка. Он просто выглядит как графический объект пуст и рисует пустое изображение. – Andreas
Зачем этот вопрос? ^^ – Andreas