/// <summary> /// Loads the texture image from a file. /// </summary> /// <param name="path">The source file path.</param> /// <returns>The <see cref="Task" /> that represents the asynchronous operation.</returns> private async Task Load(string path) { var loader = Task.Run(delegate { var bitmap = new Bitmap(Game.GetPath(path)); bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); return bitmap; }); using (var bitmap = await loader) { bitmap.PinAsReadOnly(data => this.Image.Initialize(bitmap.Width, bitmap.Height, GL.BGRA, data)); } }
/// <summary> /// Applies the convolution filter to the bitmap. /// </summary> /// <param name="bitmap">The bitmap.</param> /// <param name="colorChannels">The color channels to modify.</param> public unsafe void Apply(Bitmap bitmap, ColorChannels colorChannels = ColorChannels.All) { using (var copy = new Bitmap(bitmap)) { copy.PinAsReadOnly(sourceBits => bitmap.PinAsWriteOnly(targetBits => { var source = (uint*)sourceBits.ToPointer(); var target = (uint*)targetBits.ToPointer(); for (var y = 0; y < bitmap.Height; y++) { var y1 = bitmap.Width * (y - 1); var y2 = bitmap.Width * y; var y3 = bitmap.Width * (y + 1); for (var x = 0; x < bitmap.Width; x++) { var output = source[y2 + x]; var x1 = x - 1; var x2 = x; var x3 = x + 1; if (x <= 0) x1 = x2; if (x >= bitmap.Width - 1) x3 = x2; if (y <= 0) y1 = y2; if (y >= bitmap.Height - 1) y3 = y2; for (var i = 0; i < 4; i++) { if ((colorChannels & channel[i]) != 0) { var channelMask = mask[i]; var channelBits = shift[i]; var value = 0; value += m11 * (int)((source[y1 + x1] & channelMask) >> channelBits); value += m12 * (int)((source[y1 + x2] & channelMask) >> channelBits); value += m13 * (int)((source[y1 + x3] & channelMask) >> channelBits); value += m21 * (int)((source[y2 + x1] & channelMask) >> channelBits); value += m22 * (int)((source[y2 + x2] & channelMask) >> channelBits); value += m23 * (int)((source[y2 + x3] & channelMask) >> channelBits); value += m31 * (int)((source[y3 + x1] & channelMask) >> channelBits); value += m32 * (int)((source[y3 + x2] & channelMask) >> channelBits); value += m33 * (int)((source[y3 + x3] & channelMask) >> channelBits); value /= divisor; value += bias; if (value < Byte.MinValue) value = Byte.MinValue; if (value > Byte.MaxValue) value = Byte.MaxValue; output = (output & ~channelMask) | ((uint)value << channelBits); } } target[y2 + x] = output; } } })); } }