Сохранить содержимое визуального объекта в виде файла изображения в WPF?

Мне нужно сохранить содержимое объекта WPF в виде файла изображения. В моем приложении у меня есть диаграмма, нарисованная на объекте Canvas. Это то, что мне нужно сохранить. Холст со всеми дочерними объектами.

3 ответа

То, что вы ищете, это RenderTargetBitmap учебный класс. На странице MSDN, на которую я ссылаюсь, есть пример ее использования, и есть еще один хороший пример, который включает сохранение в файл:

RenderTargetBitmap by Eric Sinc

Вот функция, которая создает RenderTargetBitmap объект, который будет использоваться в дальнейших функциях.

public static RenderTargetBitmap ConvertToBitmap(UIElement uiElement, double resolution)
{
    var scale = resolution / 96d;

    uiElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
    var sz = uiElement.DesiredSize;
    var rect = new Rect(sz);
    uiElement.Arrange(rect);

    var bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
    bmp.Render(uiElement);

    return bmp;
}

Эта функция c создает строковое содержимое файла JPEG и записывает его в файл:

public static void ConvertToJpeg(UIElement uiElement, string path, double resolution)
{
    var jpegString = CreateJpeg(ConvertToBitmap(uiElement, resolution));

    if (path != null)
    {
        try
        {
            using (var fileStream = File.Create(path))
            {
                using (var streamWriter = new StreamWriter(fileStream, Encoding.Default))
                {
                    streamWriter.Write(jpegString);
                    streamWriter.Close();
                }

                fileStream.Close();
            }
        }    

        catch (Exception ex)
        {
            //TODO: handle exception here
        }
    }
 }

Эта функция использовалась выше для создания строкового представления JPEG содержимого изображения:

public static string CreateJpeg(RenderTargetBitmap bitmap)
{
    var jpeg = new JpegBitmapEncoder();
    jpeg.Frames.Add(BitmapFrame.Create(bitmap));
    string result;

    using (var memoryStream = new MemoryStream())
    {
        jpeg.Save(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);

        using (var streamReader = new StreamReader(memoryStream, Encoding.Default))
        {
            result = streamReader.ReadToEnd();
            streamReader.Close();
        }

        memoryStream.Close();
    }

    return result;
}

Надеюсь это поможет.

С помощью учебника Эрика Синка я пришел к следующему решению: он использует win32 SaveDialog, чтобы выбрать, куда файл должен идти, и PngBitmapEncoder (многие другие доступные BitmapEncoder!), Чтобы преобразовать его во что-то, что мы можем сохранить.

Обратите внимание, что элемент, сохраняемый в этом примере, является "cnvClasses" и что размер выходных данных, преднамеренно, совпадает с размером элемента управления.

        SaveFileDialog svDlg = new SaveFileDialog();
        svDlg.Filter = "PNG files|*.png|All Files|*.*";
        svDlg.Title = "Save diagram as PNG";
        if (svDlg.ShowDialog().Value == true)
        {
            RenderTargetBitmap render = new RenderTargetBitmap((int)this.cnvClasses.ActualWidth, (int)this.cnvClasses.ActualHeight, 96, 96, PixelFormats.Pbgra32);
            render.Render(cnvClasses);
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(render));
            using (FileStream fs = new FileStream(svDlg.FileName, FileMode.Create))
                encoder.Save(fs);
        }
Другие вопросы по тегам