C# 如何从WPF窗口创建缩略图并将其转换为字节[],以便将其持久化?

C# 如何从WPF窗口创建缩略图并将其转换为字节[],以便将其持久化?,c#,wpf,image,screenshot,C#,Wpf,Image,Screenshot,我想从我的wpf窗口创建缩略图,并将其保存到数据库中,稍后再显示。有什么好办法吗 我已经开始使用RenderTargetBitmap,但我找不到任何简单的方法将其转换为字节 RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 96, 96, PixelFormats.Pbgra32); bmp.Render(myWpfWindow); 使用user32.dll和Graphics.CopyFromScreen()对我和 因为我也想从

我想从我的wpf窗口创建缩略图,并将其保存到数据库中,稍后再显示。有什么好办法吗

我已经开始使用RenderTargetBitmap,但我找不到任何简单的方法将其转换为字节

RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 96, 96, PixelFormats.Pbgra32);
bmp.Render(myWpfWindow);
使用user32.dll和Graphics.CopyFromScreen()对我和 因为我也想从用户控件中截图


谢谢

您可以使用
位图编码器
将位图编码为PNG、JPG甚至BMP文件。查看上的MSDN文档,其中有一个保存到文件流的示例。您可以将其保存到任何流


要从
RenderTargetBitmap
获取
BitmapFrame
,只需使用该方法创建它。

您可以使用
BitmapEncoder
将位图编码为PNG、JPG甚至BMP文件。查看上的MSDN文档,其中有一个保存到文件流的示例。您可以将其保存到任何流


要从
RenderTargetBitmap
获取
BitmapFrame
,只需使用该方法创建它。

Steven Robbins已经写过关于捕获控件的屏幕截图的文章,其中包含以下扩展方法:

public static class Screenshot
{
    /// <summary>
    /// Gets a JPG "screenshot" of the current UIElement
    /// </summary>
    /// <param name="source">UIElement to screenshot</param>
    /// <param name="scale">Scale to render the screenshot</param>
    /// <param name="quality">JPG Quality</param>
    /// <returns>Byte array of JPG data</returns>
    public static byte[] GetJpgImage(this UIElement source, double scale, int quality)
    {
        double actualHeight = source.RenderSize.Height;
        double actualWidth = source.RenderSize.Width;

        double renderHeight = actualHeight * scale;
        double renderWidth = actualWidth * scale;

        RenderTargetBitmap renderTarget = new RenderTargetBitmap((int) renderWidth, (int) renderHeight, 96, 96, PixelFormats.Pbgra32);
        VisualBrush sourceBrush = new VisualBrush(source);

        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();

        using (drawingContext)
        {
            drawingContext.PushTransform(new ScaleTransform(scale, scale));
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
        }
        renderTarget.Render(drawingVisual);

        JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
        jpgEncoder.QualityLevel = quality;
        jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

        Byte[] _imageArray;

        using (MemoryStream outputStream = new MemoryStream())
        {
            jpgEncoder.Save(outputStream);
            _imageArray = outputStream.ToArray();
        }

        return _imageArray;
    }
}
公共静态类截图
{
/// 
///获取当前元素的JPG“屏幕截图”
/// 
///UIElement到屏幕截图
///缩放以渲染屏幕快照
///JPG质量
///JPG数据的字节数组
公共静态字节[]GetJpgImage(此UIElement源,双刻度,整数质量)
{
双实际高度=source.RenderSize.Height;
double actualWidth=source.RenderSize.Width;
双渲染高度=实际高度*比例;
双渲染宽度=实际宽度*比例;
RenderTargetBitmap renderTarget=新的RenderTargetBitmap((int)renderWidth,(int)renderHeight,96,96,PixelFormats.Pbgra32);
VisualBrush sourceBrush=新的VisualBrush(源);
DrawingVisual DrawingVisual=新建DrawingVisual();
DrawingContext DrawingContext=drawingVisual.RenderOpen();
使用(drawingContext)
{
PushTransform(新的ScaleTransform(scale,scale));
drawingContext.DrawRectangle(sourceBrush,null,new Rect(新点(0,0),新点(实际宽度,实际高度));
}
renderTarget.Render(drawingVisual);
JpegBitmapEncoder jpgEncoder=新的JpegBitmapEncoder();
jpgEncoder.QualityLevel=质量;
jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
字节[]_图像数组;
使用(MemoryStream outputStream=new MemoryStream())
{
jpgEncoder.Save(outputStream);
_imageArray=outputStream.ToArray();
}
返回imageArray;
}
}
此方法接受一个控件和一个比例因子,并返回一个字节数组。因此,这似乎非常适合您的要求


进一步阅读并查看一个非常简洁的示例项目。

Steven Robbins写了一篇关于捕获控件屏幕截图的文章,其中包含以下扩展方法:

public static class Screenshot
{
    /// <summary>
    /// Gets a JPG "screenshot" of the current UIElement
    /// </summary>
    /// <param name="source">UIElement to screenshot</param>
    /// <param name="scale">Scale to render the screenshot</param>
    /// <param name="quality">JPG Quality</param>
    /// <returns>Byte array of JPG data</returns>
    public static byte[] GetJpgImage(this UIElement source, double scale, int quality)
    {
        double actualHeight = source.RenderSize.Height;
        double actualWidth = source.RenderSize.Width;

        double renderHeight = actualHeight * scale;
        double renderWidth = actualWidth * scale;

        RenderTargetBitmap renderTarget = new RenderTargetBitmap((int) renderWidth, (int) renderHeight, 96, 96, PixelFormats.Pbgra32);
        VisualBrush sourceBrush = new VisualBrush(source);

        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();

        using (drawingContext)
        {
            drawingContext.PushTransform(new ScaleTransform(scale, scale));
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
        }
        renderTarget.Render(drawingVisual);

        JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
        jpgEncoder.QualityLevel = quality;
        jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

        Byte[] _imageArray;

        using (MemoryStream outputStream = new MemoryStream())
        {
            jpgEncoder.Save(outputStream);
            _imageArray = outputStream.ToArray();
        }

        return _imageArray;
    }
}
公共静态类截图
{
/// 
///获取当前元素的JPG“屏幕截图”
/// 
///UIElement到屏幕截图
///缩放以渲染屏幕快照
///JPG质量
///JPG数据的字节数组
公共静态字节[]GetJpgImage(此UIElement源,双刻度,整数质量)
{
双实际高度=source.RenderSize.Height;
double actualWidth=source.RenderSize.Width;
双渲染高度=实际高度*比例;
双渲染宽度=实际宽度*比例;
RenderTargetBitmap renderTarget=新的RenderTargetBitmap((int)renderWidth,(int)renderHeight,96,96,PixelFormats.Pbgra32);
VisualBrush sourceBrush=新的VisualBrush(源);
DrawingVisual DrawingVisual=新建DrawingVisual();
DrawingContext DrawingContext=drawingVisual.RenderOpen();
使用(drawingContext)
{
PushTransform(新的ScaleTransform(scale,scale));
drawingContext.DrawRectangle(sourceBrush,null,new Rect(新点(0,0),新点(实际宽度,实际高度));
}
renderTarget.Render(drawingVisual);
JpegBitmapEncoder jpgEncoder=新的JpegBitmapEncoder();
jpgEncoder.QualityLevel=质量;
jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
字节[]_图像数组;
使用(MemoryStream outputStream=new MemoryStream())
{
jpgEncoder.Save(outputStream);
_imageArray=outputStream.ToArray();
}
返回imageArray;
}
}
此方法接受一个控件和一个比例因子,并返回一个字节数组。因此,这似乎非常适合您的要求


进一步阅读,请查看一个非常简洁的示例项目。

RenderTargetBitmap
很好。@AngelWPF是的,但是如何从这里获取字节?我在RenderTargetBitmap上没有任何流?
RenderTargetBitmap
很好。@AngelWPF是的,但是如何从这里获取字节?我在RenderTargetBitmap上没有任何流?谢谢,它为我工作了。尽管使用renderTargetBitmap.Render(mywpfindow);不会将图像大小调整为RenderTargetBitmap大小,而是裁剪图像的左上角。知道如何调整它的大小吗?谢谢,谢谢,这对我有用。尽管使用renderTargetBitmap.Render(mywpfindow);不会将图像大小调整为RenderTargetBitmap大小,而是裁剪图像的左上角。知道如何调整它的大小吗?谢谢