private void OverlayControl_OnTintFilterSelected(object sender, RoutedEventArgs e) { var oc = sender as OverlayControl; var filter = oc.FilterBox.SelectedItem as TintFilter; _overlayBlendFilter = filter.Method; UpdateOverlays(); }
private void BorderControl_OnTintFilterSelected(object sender, RoutedEventArgs e) { var bc = sender as BorderControl; var filter = bc.FilterBox.SelectedItem as TintFilter; _borderBlendFilter = filter.Method; UpdateOverlays(); }
private void SpecialControl_OnFilterSelected(object sender, RoutedEventArgs e) { var gc = sender as SpecialControl; var specialfilter = gc.SpecialFilterBox.SelectedItem as SpecialFilter; if (specialfilter != null) { _specialFilter = specialfilter.Method; } UpdateOverlays(); }
/// <summary> /// Applies the given tint to the given image, using the specified filter. /// /// Image must use the 32bppArgb pixel format. /// </summary> /// <remarks>Results will differ between big- and little-endian architectures.</remarks> public static void AddFilter(Bitmap image, Color tint, FilterMethods.BlendFilterDelegate blendFilter) { //Dont waste time trying to tint if the given color is completely transparent and the selected filter does blending that is dependent on the selected tint colour. if (tint.A == Colors.Transparent.A && tint.R == Colors.Transparent.R && tint.G == Colors.Transparent.G && tint.B == Colors.Transparent.B && !FilterMethods.IgnoresBlendColor.Contains(blendFilter)) { return; } //Dont waste time if we're not going to do anything anyway. if (blendFilter == FilterMethods.None) { return; } var rect = new Rectangle(0, 0, image.Width, image.Height); var imagedata = image.LockBits(rect, ImageLockMode.ReadWrite, image.PixelFormat); var imagedepth = Image.GetPixelFormatSize(imagedata.PixelFormat) / 8; var imagebuffer = new byte[imagedata.Width * imagedata.Height * imagedepth]; Marshal.Copy(imagedata.Scan0, imagebuffer, 0, imagebuffer.Length); Parallel.For(0, imagedata.Width, x => { for (int y = 0; y < imagedata.Height; y++) { var offset = (y * imagedata.Width + x) * imagedepth; //The 32bppArgb format lies to us in regards to the order of channels because of endian-ness. On little-endian architecture the byte-order is BGRA instead of ARGB... var B = imagebuffer[offset + 0]; var G = imagebuffer[offset + 1]; var R = imagebuffer[offset + 2]; var A = imagebuffer[offset + 3]; var result = blendFilter(R, G, B, A, tint.R, tint.G, tint.B, tint.A); imagebuffer[offset + 0] = (byte)result.Item3; imagebuffer[offset + 1] = (byte)result.Item2; imagebuffer[offset + 2] = (byte)result.Item1; imagebuffer[offset + 3] = (byte)result.Item4; } }); Marshal.Copy(imagebuffer, 0, imagedata.Scan0, imagebuffer.Length); image.UnlockBits(imagedata); }