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
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.
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.