/// <summary> /// Apply filter. /// </summary> /// <param name="bmData">Bitmap data</param> private unsafe void ApplyHSB(BitmapData bmData) { byte *p = (byte *)bmData.Scan0.ToPointer(); int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; float length = values.Length - 1; Parallel.For(0, height, y => { int x, ystride, k; HSB hsb; RGB rgb; ystride = y * stride; for (x = 0; x < width; x++) { k = ystride + x * 4; hsb = HSB.FromRGB(p[k + 2], p[k + 1], p[k]); hsb.Brightness = values[(int)(hsb.Brightness * length)]; rgb = hsb.ToRGB; p[k + 2] = rgb.Red; p[k + 1] = rgb.Green; p[k] = rgb.Blue; } } ); return; }
/// <summary> /// Apply filter. /// </summary> /// <param name="bmData">Bitmap data</param> public unsafe void Apply(BitmapData bmData) { byte *p = (byte *)bmData.Scan0.ToPointer(); int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; Parallel.For(0, height, j => { HSB hsb; RGB rgb; int i, k, jstride = j * stride; for (i = 0; i < width; i++) { k = jstride + i * 4; hsb = HSB.FromRGB(p[k + 2], p[k + 1], p[k + 0]); hsb.Hue = Maths.Scale(hsb.Hue + hue, 0, 360); hsb.Saturation += saturation; hsb.Brightness += brightness; rgb = hsb.ToRGB; p[k + 0] = rgb.Blue; p[k + 1] = rgb.Green; p[k + 2] = rgb.Red; } } ); return; }
/// <summary> /// Apply filter. /// </summary> /// <param name="bmData">Bitmap data</param> /// <param name="bmSrc">Bitmap data</param> private unsafe void ApplyHSB(BitmapData bmData, BitmapData bmSrc) { byte *p = (byte *)bmData.Scan0.ToPointer(), pSrc = (byte *)bmSrc.Scan0.ToPointer(); int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; float length = values.GetLength(0) - 1; Parallel.For(0, height, j => { HSB lumI; HSB lumIx; RGB rgb; int i, k, k1, k2, jstride = j * stride; for (i = 0; i < width; i++) { k = jstride + i * 4; k1 = k + 1; k2 = k + 2; lumI = HSB.FromRGB(p[k2], p[k1], p[k]); lumIx = HSB.FromRGB(pSrc[k2], pSrc[k1], pSrc[k]); lumI.Brightness = this.values[(int)(lumI.Brightness * length), (int)(lumIx.Brightness * length)]; rgb = lumI.ToRGB; p[k2] = rgb.Red; p[k1] = rgb.Green; p[k] = rgb.Blue; } } ); return; }
/// <summary> /// Apply filter. /// </summary> /// <param name="bmData">Bitmap data</param> public unsafe void Apply(BitmapData bmData) { byte *p = (byte *)bmData.Scan0.ToPointer(); int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; Parallel.For(0, height, j => { HSB hsb; RGB rgb; int i, k, jstride = j * stride; for (i = 0; i < width; i++) { // This function modifies a given image in order to keep a specific hue // (given too) and to desaturate the rest of the image. This procedure // originates a image with black and white colormap, excluding the parts // colored with that hue. // Victor Martnez Cagigal, 23/02/2015 // // Designed for UMapx.NET by Valery Asiryan, 2018. k = jstride + i * 4; // Convert to hsb: hsb = HSB.FromRGB(p[k + 2], p[k + 1], p[k + 0]); // Getting hue and saturation parameters: float hue = hsb.Hue, saturation = hsb.Saturation; // Applying filter: if (min < max) { hsb.Saturation = (hue > min && hue < max) ? saturation : 0; } else { hsb.Saturation = ((hue > min && hue <= 360) || (hue < max && hue >= 0)) ? saturation : 0; } // Convert to rgb: rgb = hsb.ToRGB; p[k + 0] = rgb.Blue; p[k + 1] = rgb.Green; p[k + 2] = rgb.Red; } } ); return; }
/// <summary> /// Apply filter. /// </summary> /// <param name="bmData">Bitmap data</param> /// <param name="bmMax">Bitmap data</param> /// <param name="bmMin">Bitmap data</param> private unsafe void ApplyHSB(BitmapData bmData, BitmapData bmMax, BitmapData bmMin) { byte *p = (byte *)bmData.Scan0.ToPointer(); byte *pMax = (byte *)bmMax.Scan0.ToPointer(); byte *pMin = (byte *)bmMin.Scan0.ToPointer(); int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; float required = 1.0f - this.contrast; Parallel.For(0, height, j => { HSB imag; HSB imax; HSB imin; RGB rgb; int i, k, k1, k2, jstride = j * stride; float mag, max, min; float num1, num2, num3; for (i = 0; i < width; i++) { k = jstride + i * 4; k1 = k + 1; k2 = k + 2; imag = HSB.FromRGB(p[k2], p[k1], p[k]); imax = HSB.FromRGB(pMax[k2], pMax[k1], pMax[k]); imin = HSB.FromRGB(pMin[k2], pMin[k1], pMin[k]); mag = imag.Brightness; max = imax.Brightness; min = imin.Brightness; num1 = max - min; if (num1 < required) { num2 = min + (required - num1) * min / (num1 - 1f); min = Maths.Float(num2); max = Maths.Float(num2 + required); } num1 = max - min; num3 = mag - min; if (num1 > 0) { imag.Brightness = num3 / num1; rgb = imag.ToRGB; p[k2] = rgb.Red; p[k1] = rgb.Green; p[k] = rgb.Blue; } } } ); }
/// <summary> /// Converts a Bitmap to an HSB structure with or without alpha-channel. /// </summary> /// <param name="bmData">Bitmap data</param> /// <param name="alpha">Alpha-channel</param> /// <returns>HSB structure array</returns> public unsafe static float[][,] ToHSB(this BitmapData bmData, bool alpha = false) { // params int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; byte *p = (byte *)bmData.Scan0.ToPointer(); // matrices float[,] x = new float[height, width]; float[,] y = new float[height, width]; float[,] z = new float[height, width]; // with alpha channel if (alpha) { float[,] a = new float[height, width]; Parallel.For(0, height, j => { HSB mdl; int i, k, jstride = j * stride; for (i = 0; i < width; i++) { // shift: k = jstride + i * 4; mdl = HSB.FromRGB(p[k + 2], p[k + 1], p[k + 0]); x[j, i] = mdl.Hue; y[j, i] = mdl.Saturation; z[j, i] = mdl.Brightness; a[j, i] = p[k + 3] / 255.0f; } }); return(new float[][, ] { x, y, z, a }); } // without alpha channel Parallel.For(0, height, j => { HSB mdl; int i, k, jstride = j * stride; for (i = 0; i < width; i++) { // shift: k = jstride + i * 4; mdl = HSB.FromRGB(p[k + 2], p[k + 1], p[k + 0]); x[j, i] = mdl.Hue; y[j, i] = mdl.Saturation; z[j, i] = mdl.Brightness; } }); return(new float[][, ] { x, y, z }); }