Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
 Как сделать скриншот области в canvas-е ?  [new]
iceman3141592
Member

Откуда:
Сообщений: 9
Всем привет. Нужно сделать одну вещь, а не получается. Есть canvas, на нем кнопка и текст (текст в Rectangle, только не спрашивайте, почему сразу не в TextBlock, а с извртом, ну просто так как то игрался и пришло в голову). Хочу сделать скриншот любого компонента на canvas-е. Знаю, как сделать скриншот canvas-а, а вот некоторой площади на нем - нет :( Как только не извращался, а все равно не удается сделать так, чтобы сохранялась картинка с нужной областью и размером равным этой области. Удается только размер подогнать, но содержимое содержит уменьшенную копию всего канваса с выделенным местом нужной области...
Извращаюсь с sourceBrush и даже с drawingContext.PushClip(clipGeometry), но что то никак. Подскажите, пожалуйста, как сделать так, чтобы при выделаении некоторой области на канвасе, делался скрин этой области только и размера, равного размеру области. Вроде легкое, наверняка, но я чувствую, что что-то подзабыл...

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Button Content="Click" Click="cmd_Click" />
        <Canvas Name="canvas">
            <Button Canvas.Left="10" Canvas.Top="20" Content="sdfsdfsdf" />
            <Rectangle Canvas.Left="50" Canvas.Top="100" Width="50" Height="50">
                <Rectangle.Fill>
                    <VisualBrush>
                        <VisualBrush.Visual>
                            <TextBlock Text="AA" Background="Yellow" />
                        </VisualBrush.Visual>
                    </VisualBrush>
                </Rectangle.Fill>
            </Rectangle>
        </Canvas>        
    </StackPanel>
</Window>


public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public static byte[] GetScreenShot(UIElement source, Rect size, double scale, int quality)
        {

            double renderHeight = source.RenderSize.Height * scale;
            double renderWidth = source.RenderSize.Width * scale;
            RenderTargetBitmap renderTarget = new RenderTargetBitmap((int) size.Width, (int) size.Height, 94, 94, PixelFormats.Pbgra32);

            VisualBrush sourceBrush = new VisualBrush(source);

            sourceBrush.Stretch = Stretch.Uniform;
            sourceBrush.Viewbox = new Rect(0.1, 0.5, 1, 1);
            sourceBrush.ViewboxUnits = BrushMappingMode.RelativeToBoundingBox;

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

            RectangleGeometry clipGeometry = new RectangleGeometry(size);
            using (drawingContext)
            {
                // drawingContext.PushClip(clipGeometry);
                drawingContext.DrawRectangle(sourceBrush, null, new Rect(0, 0, size.Width, size.Height));
            }
            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;
        }

        private void cmd_Click(object sender, RoutedEventArgs e)
        {
            double x = 50;
            double y = 100;

            Rect rect = new Rect(x, y, 50, 50);
            byte[] screenshot = GetScreenShot(canvas, rect, 1.0, 90);

            FileStream fileStream = new FileStream("Capture.jpg", FileMode.Create, FileAccess.Write);
            BinaryWriter binaryWriter = new BinaryWriter(fileStream);
            binaryWriter.Write(screenshot);
            binaryWriter.Close();
        }
    }


Заранее, спасибо !
9 май 12, 01:46    [12525699]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать скриншот области в canvas-е ?  [new]
AlexeiK
Member

Откуда:
Сообщений: 2859
iceman3141592,

ошибаешься с DPI. 96 надо , вместо 94.
10 май 12, 10:43    [12528460]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать скриншот области в canvas-е ?  [new]
iceman3141592
Member

Откуда:
Сообщений: 9
Торопился получить важный ответ, опечатался.

P.S. а может быть я имел в виду 120dpi ?
13 май 12, 20:27    [12546483]     Ответить | Цитировать Сообщить модератору
Все форумы / WPF, Silverlight Ответить