1

I would like to create Thumbnail from my wpf window and would like to save it into database and display it later. Is there any good solution?

I have started with RenderTargetBitmap but I can't find any easy way to get it into bytes.

RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 96, 96, PixelFormats.Pbgra32);
bmp.Render(myWpfWindow);

Using user32.dll and Graphics.CopyFromScreen() is not good for me and as it is here because I want to do a screenshot from user controls as well.

Thanks

Community
  • 1
  • 1
Marek
  • 2,419
  • 6
  • 34
  • 38

2 Answers2

5

Steven Robbins has written a great blog post about capturing a screenshot of a control, which contains the following extension method:

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;
    }
}

This method takes a control and a scale factor and returns a byte array. So this seems to be a quite good fit with your requirements.

Check out the post for further reading and an example project that is quite neat.

Erik Öjebo
  • 10,821
  • 4
  • 54
  • 75
0

You can use a BitmapEncoder to encode your Bitmap to a PNG, JPG or even BMP file. Check the MSDN documentation on BitmapEncoder.Frames, which has an example that saves to a FileStream. You can save it to any stream.

To get the BitmapFrame from the RenderTargetBitmap, simply create it using the BitmapFrame.Create(BitmapSource) method.

robertos
  • 1,810
  • 10
  • 12
  • Thanks it worked for me. Although using renderTargetBitmap.Render(myWpfWindow); Does not resize image to RenderTargetBitmap size but rather crops top left corner of it. Any idea how to resize it? thanks – Marek Oct 14 '11 at 13:00