프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / FinalService / FinalServiceBase / MarkupToPDF / Common / XamlToPngConverter.cs @ 490208bd

이력 | 보기 | 이력해설 | 다운로드 (3.81 KB)

1 42d49521 taeseongkim

2
using System;
3
using System.Collections.Generic;
4
using System.IO;
5
using System.Reflection;
6
using System.Threading;
7
using System.Windows;
8
using System.Windows.Markup;
9
using System.Windows.Media;
10
using System.Windows.Media.Imaging;
11
12
13
namespace XAMLtoPNG
14
{
15
  public enum ScaleTO
16
  {
17
    OriginalSize=1,
18
    TargetSize=2
19
  }
20
21
  /// <summary>
22
  /// Source: http://blog.galasoft.ch/archive/2008/10/10/converting-and-customizing-xaml-to-png-with-server-side-wpf.aspx
23
  /// </summary>
24
  public class XamlToPngConverter
25
  {
26
    public void Convert(Stream xamlInput,
27
      double width, 
28
      double height,
29
      double dpiX,
30
      double dpiY,
31
      ScaleTO thisScale,
32
      Stream pngOutput)
33
    {
34
      try
35
      {
36
        // Round width and height to simplify
37
        width = Math.Round(width);
38
        height = Math.Round(height);
39
40
        Thread pngCreationThread = new Thread((ThreadStart) delegate()
41
        {
42
          FrameworkElement element = null;
43
44
          try
45
          {
46
            var inputElement = XamlReader.Load(xamlInput) as FrameworkElement;
47
48
            var viewbox = new System.Windows.Controls.Viewbox();
49
            viewbox.Stretch = Stretch.Fill;
50
            viewbox.Child = inputElement;
51
            viewbox.Width = width;
52
            viewbox.Height = height;
53
54
            element = viewbox;
55
          }
56
          catch (XamlParseException)
57
          {
58
          }
59
60
          if (element != null)
61
          {
62
            Size renderingSize = new Size(width, height);
63
            element.Measure(renderingSize);
64
            Rect renderingRectangle = new Rect(renderingSize);
65
            element.Arrange(renderingRectangle);
66
67
            BitmapSource xamlBitmap = RenderToBitmap(element, width, height, dpiX, dpiY, thisScale);
68
            try
69
            {
70
              PngBitmapEncoder enc = new PngBitmapEncoder();
71
              enc.Frames.Add(BitmapFrame.Create(xamlBitmap));
72
              enc.Save(pngOutput);
73
            }
74
            catch (ObjectDisposedException)
75
            {
76
              // IF the operation lasted too long, the object might be disposed already
77
            }
78
          }
79
        });
80
81
        pngCreationThread.IsBackground = true;
82
        pngCreationThread.SetApartmentState(ApartmentState.STA);
83
        pngCreationThread.Start();
84
        pngCreationThread.Join();
85
      }
86
      catch (Exception Exp)
87
      {
88
        throw Exp;
89
      }
90
91
      try
92
      {
93
        if (pngOutput.Length == 0)
94
        {
95
          throw new TimeoutException();
96
        }
97
      }
98
      catch (ObjectDisposedException)
99
      {
100
        // If the object was disposed, it means that the Stream is ready.
101
      }
102
    }
103
104
    private BitmapSource RenderToBitmap(FrameworkElement target,
105
                                        double width, 
106
                                        double height,
107
                                        double dpiX,
108
                                        double dpiY,
109
                                        ScaleTO thisScale)
110
    {
111
      Rect bounds;
112
113
      switch (thisScale)
114
      {
115
        case ScaleTO.OriginalSize:
116
          bounds = VisualTreeHelper.GetDescendantBounds(target);
117
          break;
118
        case ScaleTO.TargetSize:
119
          bounds = new Rect(0, 0, width,height);
120
          break;
121
        default:
122
          throw new ArgumentException(string.Format("The scaling mode: {0} is not supported.", thisScale.ToString()));
123
      }
124
125
      RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int) target.ActualWidth,
126
        (int)target.ActualHeight, dpiX, dpiY, PixelFormats.Pbgra32);
127
128
      DrawingVisual visual = new DrawingVisual();
129
      using (DrawingContext context = visual.RenderOpen())
130
      {
131
        VisualBrush brush = new VisualBrush(target);
132
        context.DrawRectangle(brush, null, new Rect(new Point(), bounds.Size));
133
      }
134
135
      renderBitmap.Render(visual);
136
      return renderBitmap;
137
    }
138
  }
139
}
클립보드 이미지 추가 (최대 크기: 500 MB)