1 | using System;
|
---|
2 | using System.IO;
|
---|
3 | using System.ComponentModel;
|
---|
4 | using System.Reflection;
|
---|
5 | using System.Windows;
|
---|
6 | using System.Windows.Media.Imaging;
|
---|
7 |
|
---|
8 | namespace SharpVectors.Runtime
|
---|
9 | {
|
---|
10 | public class EmbeddedBitmapSource : BitmapSource
|
---|
11 | {
|
---|
12 | #region Private Fields
|
---|
13 |
|
---|
14 | private BitmapImage _bitmap;
|
---|
15 | private MemoryStream _stream;
|
---|
16 |
|
---|
17 | #endregion Fields
|
---|
18 |
|
---|
19 | #region Constructors and Destructor
|
---|
20 |
|
---|
21 | public EmbeddedBitmapSource()
|
---|
22 | : base()
|
---|
23 | {
|
---|
24 | //
|
---|
25 | // Set the _useVirtuals private fields of BitmapSource to true. otherwise you will not be able to call BitmapSource methods.
|
---|
26 | FieldInfo field = typeof(BitmapSource).GetField("_useVirtuals",
|
---|
27 | BindingFlags.NonPublic | BindingFlags.Instance);
|
---|
28 | field.SetValue(this, true);
|
---|
29 | }
|
---|
30 |
|
---|
31 | // ------------------------------------------------------------------
|
---|
32 |
|
---|
33 | public EmbeddedBitmapSource(MemoryStream stream)
|
---|
34 | : this()
|
---|
35 | {
|
---|
36 | if (stream == null)
|
---|
37 | throw new ArgumentNullException("stream");
|
---|
38 |
|
---|
39 | _stream = stream;
|
---|
40 | //
|
---|
41 | // Associated this class with source.
|
---|
42 | this.BeginInit();
|
---|
43 |
|
---|
44 | _bitmap = new BitmapImage();
|
---|
45 |
|
---|
46 | _bitmap.BeginInit();
|
---|
47 | _bitmap.StreamSource = _stream;
|
---|
48 | _bitmap.EndInit();
|
---|
49 |
|
---|
50 | this.InitWicInfo(_bitmap);
|
---|
51 | this.EndInit();
|
---|
52 | }
|
---|
53 |
|
---|
54 | #endregion Constructors
|
---|
55 |
|
---|
56 | #region Public Properties
|
---|
57 |
|
---|
58 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
---|
59 | public EmbeddedBitmapData Data
|
---|
60 | {
|
---|
61 | get
|
---|
62 | {
|
---|
63 | return new EmbeddedBitmapData(_stream);
|
---|
64 | }
|
---|
65 | set
|
---|
66 | {
|
---|
67 | BeginInit();
|
---|
68 |
|
---|
69 | _stream = value.Stream;
|
---|
70 |
|
---|
71 | _bitmap = new BitmapImage();
|
---|
72 | _bitmap.BeginInit();
|
---|
73 | _bitmap.StreamSource = _stream;
|
---|
74 | _bitmap.EndInit();
|
---|
75 |
|
---|
76 | InitWicInfo(_bitmap);
|
---|
77 | EndInit();
|
---|
78 | }
|
---|
79 | }
|
---|
80 |
|
---|
81 | #endregion Properties
|
---|
82 |
|
---|
83 | #region Protected Methods
|
---|
84 |
|
---|
85 | protected override void CloneCore(Freezable sourceFreezable)
|
---|
86 | {
|
---|
87 | EmbeddedBitmapSource cloneSource = (EmbeddedBitmapSource)sourceFreezable;
|
---|
88 | CopyFrom(cloneSource);
|
---|
89 | //base.CloneCore( sourceFreezable );
|
---|
90 | }
|
---|
91 |
|
---|
92 | protected override void CloneCurrentValueCore(Freezable sourceFreezable)
|
---|
93 | {
|
---|
94 | EmbeddedBitmapSource cloneSource = (EmbeddedBitmapSource)sourceFreezable;
|
---|
95 | CopyFrom(cloneSource);
|
---|
96 | //base.CloneCurrentValueCore( sourceFreezable );
|
---|
97 | }
|
---|
98 |
|
---|
99 | protected override void GetAsFrozenCore(Freezable sourceFreezable)
|
---|
100 | {
|
---|
101 | EmbeddedBitmapSource cloneSource = (EmbeddedBitmapSource)sourceFreezable;
|
---|
102 | CopyFrom(cloneSource);
|
---|
103 | //base.GetAsFrozenCore( sourceFreezable );
|
---|
104 | }
|
---|
105 |
|
---|
106 | protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
|
---|
107 | {
|
---|
108 | EmbeddedBitmapSource cloneSource = (EmbeddedBitmapSource)sourceFreezable;
|
---|
109 | CopyFrom(cloneSource);
|
---|
110 | //base.GetCurrentValueAsFrozenCore( sourceFreezable );
|
---|
111 | }
|
---|
112 |
|
---|
113 | protected override Freezable CreateInstanceCore()
|
---|
114 | {
|
---|
115 | return new EmbeddedBitmapSource();
|
---|
116 | }
|
---|
117 |
|
---|
118 | #endregion Override Methods
|
---|
119 |
|
---|
120 | #region Private Methods
|
---|
121 |
|
---|
122 | /// <summary>
|
---|
123 | /// Call BeginInit every time the WICSourceHandle is going to be change.
|
---|
124 | /// again this methods is not exposed and reflection is needed.
|
---|
125 | /// </summary>
|
---|
126 | private void BeginInit()
|
---|
127 | {
|
---|
128 | FieldInfo field = typeof(BitmapSource).GetField(
|
---|
129 | "_bitmapInit", BindingFlags.NonPublic | BindingFlags.Instance);
|
---|
130 | MethodInfo beginInit = field.FieldType.GetMethod(
|
---|
131 | "BeginInit", BindingFlags.Public | BindingFlags.Instance);
|
---|
132 | beginInit.Invoke(field.GetValue(this), null);
|
---|
133 | }
|
---|
134 |
|
---|
135 | /// <summary>
|
---|
136 | /// Call EndInit after the WICSourceHandle was changed and after using BeginInit.
|
---|
137 | /// again this methods is not exposed and reflection is needed.
|
---|
138 | /// </summary>
|
---|
139 | private void EndInit()
|
---|
140 | {
|
---|
141 | FieldInfo field = typeof(BitmapSource).GetField(
|
---|
142 | "_bitmapInit", BindingFlags.NonPublic | BindingFlags.Instance);
|
---|
143 | MethodInfo endInit = field.FieldType.GetMethod(
|
---|
144 | "EndInit", BindingFlags.Public | BindingFlags.Instance);
|
---|
145 | endInit.Invoke(field.GetValue(this), null);
|
---|
146 | }
|
---|
147 |
|
---|
148 | /// <summary>
|
---|
149 | /// Set the WicSourceHandle property with the source associated with this class.
|
---|
150 | /// again this methods is not exposed and reflection is needed.
|
---|
151 | /// </summary>
|
---|
152 | /// <param name="source"></param>
|
---|
153 | private void InitWicInfo(BitmapSource source)
|
---|
154 | {
|
---|
155 | //
|
---|
156 | // Use reflection to get the private property WicSourceHandle Get and Set methods.
|
---|
157 | PropertyInfo wicSourceHandle = typeof(BitmapSource).GetProperty(
|
---|
158 | "WicSourceHandle", BindingFlags.NonPublic | BindingFlags.Instance);
|
---|
159 |
|
---|
160 | MethodInfo wicSourceHandleGetMethod = wicSourceHandle.GetGetMethod(true);
|
---|
161 | MethodInfo wicSourceHandleSetMethod = wicSourceHandle.GetSetMethod(true);
|
---|
162 | //
|
---|
163 | // Call the Get method of the WicSourceHandle of source.
|
---|
164 | object wicHandle = wicSourceHandleGetMethod.Invoke(source, null);
|
---|
165 | //
|
---|
166 | // Call the Set method of the WicSourceHandle of this with the value from source.
|
---|
167 | wicSourceHandleSetMethod.Invoke(this, new object[] { wicHandle });
|
---|
168 | }
|
---|
169 |
|
---|
170 | private void CopyFrom(EmbeddedBitmapSource source)
|
---|
171 | {
|
---|
172 | this.BeginInit();
|
---|
173 |
|
---|
174 | _bitmap = source._bitmap;
|
---|
175 |
|
---|
176 | this.InitWicInfo(_bitmap);
|
---|
177 | this.EndInit();
|
---|
178 | }
|
---|
179 |
|
---|
180 | #endregion Methods
|
---|
181 | }
|
---|
182 | }
|
---|