Spring – Rev 1
?pathlinks?
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Spring.Utilities
{
public static class Helpers
{
#region Public Methods
/// <summary>
/// Enable double buffering for an arbitrary control.
/// </summary>
/// <param name="control">the control to enable double buffering for</param>
/// <returns>true on success</returns>
/// <remarks>Do not enable double buffering on RDP: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793</remarks>
public static bool SetDoubleBuffered(this Control control)
{
if (SystemInformation.TerminalServerSession)
{
return false;
}
var dgvType = control.GetType();
var pi = dgvType.GetProperty("DoubleBuffered",
BindingFlags.Instance | BindingFlags.NonPublic);
if (pi == null)
{
return false;
}
pi.SetValue(control, true, null);
return true;
}
/// <summary>
/// Crop whitespace around a bitmap.
/// </summary>
/// <param name="bmp">the bitmap to process</param>
/// <returns>a cropped bitmap</returns>
/// <remarks>https://stackoverflow.com/users/329367/darren</remarks>
public static Bitmap Crop(Bitmap bmp)
{
var w = bmp.Width;
var h = bmp.Height;
bool AllWhiteRow(int row)
{
for (var i = 0; i < w; ++i)
{
if (bmp.GetPixel(i, row)
.R !=
255)
{
return false;
}
}
return true;
}
bool AllWhiteColumn(int col)
{
for (var i = 0; i < h; ++i)
{
if (bmp.GetPixel(col, i)
.R !=
255)
{
return false;
}
}
return true;
}
var topmost = 0;
for (var row = 0; row < h; ++row)
{
if (AllWhiteRow(row))
{
topmost = row;
}
else
{
break;
}
}
var bottommost = 0;
for (var row = h - 1; row >= 0; --row)
{
if (AllWhiteRow(row))
{
bottommost = row;
}
else
{
break;
}
}
int leftmost = 0, rightmost = 0;
for (var col = 0; col < w; ++col)
{
if (AllWhiteColumn(col))
{
leftmost = col;
}
else
{
break;
}
}
for (var col = w - 1; col >= 0; --col)
{
if (AllWhiteColumn(col))
{
rightmost = col;
}
else
{
break;
}
}
if (rightmost == 0)
{
rightmost = w; // As reached left
}
if (bottommost == 0)
{
bottommost = h; // As reached top.
}
var croppedWidth = rightmost - leftmost;
var croppedHeight = bottommost - topmost;
if (croppedWidth == 0) // No border on left or right
{
leftmost = 0;
croppedWidth = w;
}
if (croppedHeight == 0) // No border on top or bottom
{
topmost = 0;
croppedHeight = h;
}
try
{
var target = new Bitmap(croppedWidth, croppedHeight);
using (var g = Graphics.FromImage(target))
{
g.DrawImage(bmp,
new RectangleF(0, 0, croppedWidth, croppedHeight),
new RectangleF(leftmost, topmost, croppedWidth, croppedHeight),
GraphicsUnit.Pixel);
}
return target;
}
catch (Exception ex)
{
throw new Exception(
$"Values are topmost={topmost} btm={bottommost} left={leftmost} right={rightmost} croppedWidth={croppedWidth} croppedHeight={croppedHeight}",
ex);
}
}
public static string Md5Hash(string input)
{
// Use input string to calculate MD5 hash
using (var md5 = MD5.Create())
{
var inputBytes = Encoding.ASCII.GetBytes(input);
var hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
var sb = new StringBuilder();
foreach (var hashByte in hashBytes)
{
sb.Append(hashByte.ToString("X2"));
}
return sb.ToString();
}
}
public static string Sha1Hash(string input)
{
using (var sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
var sb = new StringBuilder(hash.Length * 2);
foreach (var b in hash)
{
// can be "x2" if you want lowercase
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
}
public static async Task<byte[]> LoadResource(string resource)
{
var assembly = Assembly.GetExecutingAssembly();
using (var manifestResourceStream = assembly.GetManifestResourceStream(resource))
{
if (manifestResourceStream == null)
{
return null;
}
var memoryStream = new MemoryStream();
await manifestResourceStream.CopyToAsync(memoryStream);
memoryStream.Position = 0L;
return memoryStream.ToArray();
}
}
public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : Control
{
if (control.InvokeRequired)
{
control.BeginInvoke((MethodInvoker) delegate { action(control); });
return;
}
action(control);
}
public static T MapValueToRange<T>(this T value, T xMin, T xMax, T yMin, T yMax)
where T : struct, IComparable<T>, IConvertible =>
(dynamic) yMin +
((dynamic) yMax - (dynamic) yMin) * ((dynamic) value - (dynamic) xMin) / ((dynamic) xMax - (dynamic) xMin);
public static IEnumerable<TU> SequenceSubtract<TU, TV>(this IEnumerable<TU> a,
IEnumerable<TV> b,
Func<TU, TV, bool> cmp)
{
var eb = new List<TV>(b);
using (var ea = a.GetEnumerator())
{
while (ea.MoveNext())
{
if (ea.Current == null)
{
continue;
}
foreach (var ib in eb)
{
if (cmp.Invoke(ea.Current, ib))
{
continue;
}
yield return ea.Current;
break;
}
}
}
}
#endregion
}
}