Создание изображения из экранного вывода WPF и Silverlight. Попросту Snapshot из Silverlight и WPF.
Мне не терпиться поделиться новостью, что несколькими строчками кода можно создать изображение из любого элемента Silverlight или WPF. Для этого не нужно использовать Windows API (хотя тоже можно, как вариант).
Применяются для получения изображений классы из пространства имен .NET Framework System.Windows.Media.Imaging и System.Windows.Media.
Можно получить снэпшет как с любого элемента, так и со всего окна сразу. Полученное изображение в Silverlight можно передать по WCF на сервер или даже предложить пользователю сохранить на диск.
Я создал примеры для WPF и Silverlight. Мне требуется их осмыслить, немного причесать перед выкладыванием, но срочный проект на работе забрал все мои ресурсы, в т.ч. свободного времени. Я заимусь этим позже, тк всеравно это будет использоватся по работе. Но я считаю, что мы все грамотные разработчики, поэтому для нас действует принцип: “Осведомлен, значит вооружен”.
Итак, я вас вооружил :) Погуглите, поищите в MSDN-форумах, походите по блогам. В том числе вы наткнетесь и на мои сырые примеры в комментариях.
И всетаки вот куски кода, скорее всего они будут вам очень полезны, если я не доберусь до этого поста.
Для Silverlight
_______________________________
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Media;
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
} private void Button_Click(object sender, RoutedEventArgs e)
{
WriteableBitmap bit = new WriteableBitmap(this, null);
bit.Render(this, new MatrixTransform());
Image img = new Image();
img.Source = bit;
StackPanel1.Children.Clear(); Border border = new Border();
var brush = new SolidColorBrush(SystemColors.ActiveBorderColor);
border.BorderBrush = brush;
border.BorderThickness = new Thickness(20);
border.Child = img; StackPanel1.Children.Add(border);
}
}
}
+===============================+
<UserControl x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBox Width="100"></TextBox>
<TextBox Width="100"></TextBox>
<Button Width="100" Content="Update" Click="Button_Click"></Button>
</StackPanel>
<StackPanel x:Name="StackPanel1" Grid.Column="1" VerticalAlignment="Center">
</StackPanel>
</Grid>
</UserControl>
______________________________________________Для WPF
_______________________________
<Window x:Class="CaptureBitmapImage.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
Background="Red"
>
<Grid>
<Border>
<Button Background="Yellow" Height="23" Name="button1" Width="75" Click="button1_Click">Button</Button>
</Border>
</Grid>
</Window>
+================================+
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;namespace CaptureBitmapImage
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
} private void button1_Click(object sender, RoutedEventArgs e)
{
SaveWindowSnapshot(this, "!!!__!!!__MyWindowSnapshot.jpg"); // add Button name "button1" before
SaveWindowSnapshot(button1, "!!!__!!!__MyButtonSnapshot.jpg");
} private void SaveWindowSnapshot(Visual targetVisual, string fileName)
{
Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
double myDeviceDpiX = m.M11 * 96.0;
double myDeviceDpiY = m.M22 * 96.0; BitmapSource bitmapSource = captureVisualBitmap(
targetVisual,
myDeviceDpiX,
myDeviceDpiY
); var imgStream = GrabSnapshotStream(bitmapSource, myDeviceDpiX, myDeviceDpiY, ImageFormats.JPG);
using (imgStream)
{
imgStream.Position = 0; var fileStream = new FileStream(@"c:/" + fileName, FileMode.OpenOrCreate);
using (fileStream)
{
for (int i = 0; i < imgStream.Length; i++)
{
fileStream.WriteByte((byte)imgStream.ReadByte());
}
}
}
} private static BitmapSource captureVisualBitmap(Visual targetVisual, double dpiX, double dpiY)
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(targetVisual); RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
(int)(bounds.Width * dpiX / 96.0),
(int)(bounds.Height * dpiY / 96.0),
dpiX,
dpiY, //PixelFormats.Default
PixelFormats.Pbgra32
); DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
VisualBrush visualBrush = new VisualBrush(targetVisual);
drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));
}
renderTargetBitmap.Render(drawingVisual); return renderTargetBitmap;
} public static MemoryStream GrabSnapshotStream(BitmapSource bitmapSource, double dpiX, double dpiY, ImageFormats imageFormats)
{
BitmapEncoder bitmapEncoder; switch (imageFormats)
{
case ImageFormats.PNG:
{
bitmapEncoder = new PngBitmapEncoder();
break;
}
case ImageFormats.BMP:
{
bitmapEncoder = new BmpBitmapEncoder();
break;
}
case ImageFormats.JPG:
{
bitmapEncoder = new JpegBitmapEncoder();
break;
}
default:
throw new NotSupportedException("The Incorrect Logic");
} bitmapEncoder.Frames.Add(BitmapFrame.Create(bitmapSource)); // Create a MemoryStream with the image.
// Returning this as a MemoryStream makes it easier to save the image to a file or simply display it anywhere.
var memoryStream = new MemoryStream();
bitmapEncoder.Save(memoryStream); return memoryStream;
} public enum ImageFormats
{
PNG,
BMP,
JPG
}
}
}Источники:
Коллеги, погуглите, при случае привиду ссылки. Я сам гуглил.
Комментарии
Отправить комментарий