将 wpf 图像控件保存到文件的最简单方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10470841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Easiest way of saving wpf Image control to a file
提问by Meh
I have a Image control inside my wpf application, which has a large image inside of it, but the control itself is only 60x150, this means it only shows a certain portion of this image. What is the easiest way of saving the visible portion to a file?
我的 wpf 应用程序中有一个 Image 控件,里面有一个大图像,但控件本身只有 60x150,这意味着它只显示该图像的某个部分。将可见部分保存到文件的最简单方法是什么?
Thank you for your help.
感谢您的帮助。
[EDIT] I ended up using code found here(which I've not been able to locate before posting here)...
[编辑] 我最终使用了此处找到的代码(在此处发布之前我无法找到该代码)...
Grid r = new Grid();
r.Background = new ImageBrush(image2.Source);
System.Windows.Size sz = new System.Windows.Size(image2.Source.Width, image2.Source.Height);
r.Measure(sz);
r.Arrange(new Rect(sz));
RenderTargetBitmap rtb = new RenderTargetBitmap((int)image2.Source.Width, (int)image2.Source.Height, 96d, 96d, PixelFormats.Default);
rtb.Render(r);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
FileStream fs = File.Open(@"C:\lol.png", FileMode.Create);
encoder.Save(fs);
fs.Close();
回答by gliderkite
You could use RenderTargetBitmapclass and BitmapEncoder.
您可以使用RenderTargetBitmap类和BitmapEncoder。
Define these methods:
定义这些方法:
void SaveToBmp(FrameworkElement visual, string fileName)
{
var encoder = new BmpBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
void SaveToPng(FrameworkElement visual, string fileName)
{
var encoder = new PngBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
// and so on for other encoders (if you want)
void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(visual);
BitmapFrame frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName))
{
encoder.Save(stream);
}
}
If you have your Imagecontrol inside a container like this:
如果您在这样的容器中拥有Image控件:
<Grid x:Name="MyGrid">
<Image Name="MyImage" Stretch="None"></Image>
</Grid>
You just need to do so:
你只需要这样做:
SaveToPng(MyGrid, "image.png");
Otherwise you can simply pass the dimensions you want when you use RenderTargetBitmap:
否则,您可以在使用 RenderTargetBitmap 时简单地传递所需的尺寸:
SaveToPng(MyImage, "image.png");
...
RenderTargetBitmap bitmap = new RenderTargetBitmap(YourWidth, YourHeight, 96, 96, PixelFormats.Pbgra32);
回答by denver
I ran into the same 'black' image issue that other did when using gliderkite's solution. The 'black' image appears to be due to the FrameworkElement's margin causing it to get rendered outside of the captured image. I found the workaround in a comment on Rick Stahl's blog
在使用 gliderkite 的解决方案时,我遇到了与其他人相同的“黑色”图像问题。“黑色”图像似乎是由于 FrameworkElement 的边距导致它在捕获的图像之外呈现。我在 Rick Stahl 博客的评论中找到了解决方法
Specifically, measuring and arranging prior to rendering gives it a chance to adjust itself to the fact there are no margins in the picture. The following is a static class I now re-use for screen captures. This is based of of gliderkite's answer and the information on Rick Stahl's blog.
具体来说,在渲染之前进行测量和排列使其有机会根据图片中没有边距的事实进行自我调整。以下是我现在重新用于屏幕捕获的静态类。这是基于 gliderkite 的回答和 Rick Stahl 博客上的信息。
public static class ScreenCapture
{
public static void SaveToBmp(FrameworkElement visual, string fileName)
{
var encoder = new BmpBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
public static void SaveToPng(FrameworkElement visual, string fileName)
{
var encoder = new PngBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
public static void SaveToJpeg(FrameworkElement visual, string fileName)
{
var encoder = new JpegBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
private static void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32);
Size visualSize = new Size(visual.ActualWidth, visual.ActualHeight);
visual.Measure(visualSize);
visual.Arrange(new Rect(visualSize));
bitmap.Render(visual);
BitmapFrame frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName))
{
encoder.Save(stream);
}
}
}