【发布时间】:2011-04-06 18:35:53
【问题描述】:
我需要将 WPF 对象的内容保存为图像文件。在我的应用程序中,我在 Canvas 对象上绘制了一个图表。这是我需要保存的。包含所有子对象的 Canvas。
【问题讨论】:
我需要将 WPF 对象的内容保存为图像文件。在我的应用程序中,我在 Canvas 对象上绘制了一个图表。这是我需要保存的。包含所有子对象的 Canvas。
【问题讨论】:
您正在寻找的是RenderTargetBitmap 类。在我链接的 MSDN 页面上有一个使用示例,还有另一个很好的示例,包括在此处保存到文件:
【讨论】:
这里是创建RenderTargetBitmap 对象的函数,将在后续函数中使用。
public static RenderTargetBitmap ConvertToBitmap(UIElement uiElement, double resolution)
{
var scale = resolution / 96d;
uiElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
var sz = uiElement.DesiredSize;
var rect = new Rect(sz);
uiElement.Arrange(rect);
var bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
bmp.Render(uiElement);
return bmp;
}
此函数创建文件的JPEG字符串内容并将其写入文件:
public static void ConvertToJpeg(UIElement uiElement, string path, double resolution)
{
var jpegString = CreateJpeg(ConvertToBitmap(uiElement, resolution));
if (path != null)
{
try
{
using (var fileStream = File.Create(path))
{
using (var streamWriter = new StreamWriter(fileStream, Encoding.Default))
{
streamWriter.Write(jpegString);
streamWriter.Close();
}
fileStream.Close();
}
}
catch (Exception ex)
{
//TODO: handle exception here
}
}
}
上面使用此函数创建图像内容的 JPEG 字符串表示:
public static string CreateJpeg(RenderTargetBitmap bitmap)
{
var jpeg = new JpegBitmapEncoder();
jpeg.Frames.Add(BitmapFrame.Create(bitmap));
string result;
using (var memoryStream = new MemoryStream())
{
jpeg.Save(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
using (var streamReader = new StreamReader(memoryStream, Encoding.Default))
{
result = streamReader.ReadToEnd();
streamReader.Close();
}
memoryStream.Close();
}
return result;
}
希望这会有所帮助。
【讨论】:
BitmapEncoder.Save 方法采用 Stream,因此它可以将数据直接转储到 FileStream 而不是所有那些复制
在 Eric Sinc 教程的帮助下,我找到了以下解决方案: 它使用 win32 SaveDialog 来选择文件的存放位置,并使用 PngBitmapEncoder(许多其他 BitmapEncoders 可用!)将其转换为我们可以保存的内容。
请注意,此示例中保存的元素是“cnvClasses”,并且输出的大小故意与控件相同。
SaveFileDialog svDlg = new SaveFileDialog();
svDlg.Filter = "PNG files|*.png|All Files|*.*";
svDlg.Title = "Save diagram as PNG";
if (svDlg.ShowDialog().Value == true)
{
RenderTargetBitmap render = new RenderTargetBitmap((int)this.cnvClasses.ActualWidth, (int)this.cnvClasses.ActualHeight, 96, 96, PixelFormats.Pbgra32);
render.Render(cnvClasses);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(render));
using (FileStream fs = new FileStream(svDlg.FileName, FileMode.Create))
encoder.Save(fs);
}
【讨论】: