Сохранение визуального элемента WPF в формате JPEG
Эта вещь сводит меня с ума.
У меня есть диаграмма Visiblox. который я сейчас экспортирую как PNG, используя следующий код:
var chart = this.CalibrationChartVisibility == Visibility.Visible ? this.calibrationChart : this.residualChart;
var transform = chart.LayoutTransform;
chart.LayoutTransform = null;
var width = (int)chart.ActualWidth;
var height = (int)chart.ActualHeight;
var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(chart);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
var stream = new MemoryStream();
encoder.Save(stream);
stream.Position = 0;
chart.LayoutTransform = transform;
return stream.ToArray();
и я получаю что-то вроде этого:
Но теперь мне нужно также экспортировать его в формате JPEG. Я думал, что это будет просто, просто измените кодировщик, но вот что я получаю:
Я попробовал это: http://social.msdn.microsoft.com/Forums/vstudio/en-US/31ac62d4-399b-4f2e-a9b9-749efe7528b6/rendertargetbitmap-to-file-problem?forum=wpf
и это: http://www.grumpydev.com/2009/01/03/taking-wpf-screenshots/
и это: получить растровое изображение из представления управления
и Эрви sugestion на этот пост: Как сохранить изображение с помощью JpegBitmapEncoder
или этот: сохранение WPF InkCanvas в JPG - изображение обрезается
и все остальное, что приходило мне в голову, но результат все тот же.
Должно быть, я что-то упускаю, но понятия не имею, что это такое.
2 ответа
Подводя итог комментариям, это кажется второстепенной проблемой, поскольку PNG, прикрепленный к этому вопросу, имеет все прозрачное, кроме линий диаграммы, а поскольку JPEG не поддерживает прозрачность, все прозрачное будет черным.
Самое простое решение - установить фон диаграммы на какой-нибудь цвет.
Отказ от ответственности: я предоставил этот ответ на вопрос System.Drawing.Image из ImageSource in Resources и собирался проголосовать, чтобы закрыть этот вопрос как дубликат другого, но не смог, потому что автор вопроса не принял ответ.
В WPF каждый элемент пользовательского интерфейса расширяет Visual
Класс, обеспечивающий поддержку рендеринга в WPF. Также есть RenderTargetBitmap
Класс, который имеет Render
Метод, который принимает Visual
Объект в качестве входного параметра. Так что вы можете установить свой ImageSource
как Source
свойство Image
и просто сделать Image
к Bitmap
образ:
Image yourImageObject = new Image();
yourImageObject.Source = yourImageSource;
RenderTargetBitmap renderTargetBitmap =
new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
renderTargetBitmap.Render(yourImageObject);
// Save to .png file
PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
pngBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream stream = File.Create(filepath))
{
pngBitmapEncoder.Save(stream);
}
Поскольку это хорошо задокументировано в интернете, я не стану повторять здесь всю историю. Чтобы узнать подробности, ознакомьтесь с разделом " Как отобразить растровое изображение" или "Распечатать визуальную страницу в WPF" на веб-сайте Dot NET Tricks, который также поможет вам с вашими требованиями к печати.
ОБНОВЛЕНИЕ >>>
Итак, большая часть этого относится к вам точно так же, за исключением того, что вы хотите использоватьJpegBitmapEncoder
объект вместо Этот пример со связанной страницы показывает другой способ сохранить изображение JPEG:
int width = 128;
int height = width;
int stride = width / 8;
byte[] pixels = new byte[height * stride];
// Define the image palette
BitmapPalette myPalette = BitmapPalettes.Halftone256;
// Creates a new empty image with the pre-defined palette
BitmapSource image = BitmapSource.Create(
width,
height,
96,
96,
PixelFormats.Indexed1,
myPalette,
pixels,
stride);
FileStream stream = new FileStream("new.jpg", FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
TextBlock myTextBlock = new TextBlock();
myTextBlock.Text = "Codec Author is: " + encoder.CodecInfo.Author.ToString();
encoder.FlipHorizontal = true;
encoder.FlipVertical = false;
encoder.QualityLevel = 30;
encoder.Rotation = Rotation.Rotate90;
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);
Пожалуйста, дайте мне знать, если у вас есть какие-либо проблемы.