Spring – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
3 using System.Drawing;
4 using System.IO;
5 using System.Reflection;
6 using System.Security.Cryptography;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10  
11 namespace Spring.Utilities
12 {
13 public static class Helpers
14 {
15 #region Public Methods
16  
17 /// <summary>
18 /// Enable double buffering for an arbitrary control.
19 /// </summary>
20 /// <param name="control">the control to enable double buffering for</param>
21 /// <returns>true on success</returns>
22 /// <remarks>Do not enable double buffering on RDP: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793</remarks>
23 public static bool SetDoubleBuffered(this Control control)
24 {
25 if (SystemInformation.TerminalServerSession)
26 {
27 return false;
28 }
29  
30 var dgvType = control.GetType();
31  
32 var pi = dgvType.GetProperty("DoubleBuffered",
33 BindingFlags.Instance | BindingFlags.NonPublic);
34  
35 if (pi == null)
36 {
37 return false;
38 }
39  
40 pi.SetValue(control, true, null);
41  
42 return true;
43 }
44  
45 /// <summary>
46 /// Crop whitespace around a bitmap.
47 /// </summary>
48 /// <param name="bmp">the bitmap to process</param>
49 /// <returns>a cropped bitmap</returns>
50 /// <remarks>https://stackoverflow.com/users/329367/darren</remarks>
51 public static Bitmap Crop(Bitmap bmp)
52 {
53 var w = bmp.Width;
54 var h = bmp.Height;
55  
56 bool AllWhiteRow(int row)
57 {
58 for (var i = 0; i < w; ++i)
59 {
60 if (bmp.GetPixel(i, row)
61 .R !=
62 255)
63 {
64 return false;
65 }
66 }
67  
68 return true;
69 }
70  
71 bool AllWhiteColumn(int col)
72 {
73 for (var i = 0; i < h; ++i)
74 {
75 if (bmp.GetPixel(col, i)
76 .R !=
77 255)
78 {
79 return false;
80 }
81 }
82  
83 return true;
84 }
85  
86 var topmost = 0;
87  
88 for (var row = 0; row < h; ++row)
89 {
90 if (AllWhiteRow(row))
91 {
92 topmost = row;
93 }
94 else
95 {
96 break;
97 }
98 }
99  
100 var bottommost = 0;
101  
102 for (var row = h - 1; row >= 0; --row)
103 {
104 if (AllWhiteRow(row))
105 {
106 bottommost = row;
107 }
108 else
109 {
110 break;
111 }
112 }
113  
114 int leftmost = 0, rightmost = 0;
115  
116 for (var col = 0; col < w; ++col)
117 {
118 if (AllWhiteColumn(col))
119 {
120 leftmost = col;
121 }
122 else
123 {
124 break;
125 }
126 }
127  
128 for (var col = w - 1; col >= 0; --col)
129 {
130 if (AllWhiteColumn(col))
131 {
132 rightmost = col;
133 }
134 else
135 {
136 break;
137 }
138 }
139  
140 if (rightmost == 0)
141 {
142 rightmost = w; // As reached left
143 }
144  
145 if (bottommost == 0)
146 {
147 bottommost = h; // As reached top.
148 }
149  
150 var croppedWidth = rightmost - leftmost;
151 var croppedHeight = bottommost - topmost;
152  
153 if (croppedWidth == 0) // No border on left or right
154 {
155 leftmost = 0;
156 croppedWidth = w;
157 }
158  
159 if (croppedHeight == 0) // No border on top or bottom
160 {
161 topmost = 0;
162 croppedHeight = h;
163 }
164  
165 try
166 {
167 var target = new Bitmap(croppedWidth, croppedHeight);
168  
169 using (var g = Graphics.FromImage(target))
170 {
171 g.DrawImage(bmp,
172 new RectangleF(0, 0, croppedWidth, croppedHeight),
173 new RectangleF(leftmost, topmost, croppedWidth, croppedHeight),
174 GraphicsUnit.Pixel);
175 }
176  
177 return target;
178 }
179 catch (Exception ex)
180 {
181 throw new Exception(
182 $"Values are topmost={topmost} btm={bottommost} left={leftmost} right={rightmost} croppedWidth={croppedWidth} croppedHeight={croppedHeight}",
183 ex);
184 }
185 }
186  
187 public static string Md5Hash(string input)
188 {
189 // Use input string to calculate MD5 hash
190 using (var md5 = MD5.Create())
191 {
192 var inputBytes = Encoding.ASCII.GetBytes(input);
193 var hashBytes = md5.ComputeHash(inputBytes);
194  
195 // Convert the byte array to hexadecimal string
196 var sb = new StringBuilder();
197  
198 foreach (var hashByte in hashBytes)
199 {
200 sb.Append(hashByte.ToString("X2"));
201 }
202  
203 return sb.ToString();
204 }
205 }
206  
207 public static string Sha1Hash(string input)
208 {
209 using (var sha1 = new SHA1Managed())
210 {
211 var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
212 var sb = new StringBuilder(hash.Length * 2);
213  
214 foreach (var b in hash)
215 {
216 // can be "x2" if you want lowercase
217 sb.Append(b.ToString("X2"));
218 }
219  
220 return sb.ToString();
221 }
222 }
223  
224 public static async Task<byte[]> LoadResource(string resource)
225 {
226 var assembly = Assembly.GetExecutingAssembly();
227  
228 using (var manifestResourceStream = assembly.GetManifestResourceStream(resource))
229 {
230 if (manifestResourceStream == null)
231 {
232 return null;
233 }
234  
235 var memoryStream = new MemoryStream();
236  
237 await manifestResourceStream.CopyToAsync(memoryStream);
238  
239 memoryStream.Position = 0L;
240  
241 return memoryStream.ToArray();
242 }
243 }
244  
245 public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : Control
246 {
247 if (control.InvokeRequired)
248 {
249 control.BeginInvoke((MethodInvoker) delegate { action(control); });
250  
251 return;
252 }
253  
254 action(control);
255 }
256  
257 public static T MapValueToRange<T>(this T value, T xMin, T xMax, T yMin, T yMax)
258 where T : struct, IComparable<T>, IConvertible =>
259 (dynamic) yMin +
260 ((dynamic) yMax - (dynamic) yMin) * ((dynamic) value - (dynamic) xMin) / ((dynamic) xMax - (dynamic) xMin);
261  
262 public static IEnumerable<TU> SequenceSubtract<TU, TV>(this IEnumerable<TU> a,
263 IEnumerable<TV> b,
264 Func<TU, TV, bool> cmp)
265 {
266 var eb = new List<TV>(b);
267  
268 using (var ea = a.GetEnumerator())
269 {
270 while (ea.MoveNext())
271 {
272 if (ea.Current == null)
273 {
274 continue;
275 }
276  
277 foreach (var ib in eb)
278 {
279 if (cmp.Invoke(ea.Current, ib))
280 {
281 continue;
282 }
283  
284 yield return ea.Current;
285  
286 break;
287 }
288 }
289 }
290 }
291  
292 #endregion
293 }
294 }