public override unsafe ColorBgra Apply (ColorBgra color, int area, int* hb, int* hg, int* hr, int* ha) { ColorBgra normalized = GetPercentileOfColor (color, area, hb, hg, hr, ha); double lerp = strength * (1 - 0.75 * color.GetIntensity ()); return ColorBgra.Lerp (color, normalized, lerp); }
public unsafe override ColorBgra ApplyWithAlpha(ColorBgra src, int area, int sum, int* hb, int* hg, int* hr) { //each slot of the histgram can contain up to area * 255. This will overflow an int when area > 32k if (area < 32768) { int b = 0; int g = 0; int r = 0; for (int i = 1; i < 256; ++i) { b += i * hb[i]; g += i * hg[i]; r += i * hr[i]; } int alpha = sum / area; int div = area * 255; return ColorBgra.FromBgraClamped (b / div, g / div, r / div, alpha); } else { //use a long if an int will overflow. long b = 0; long g = 0; long r = 0; for (long i = 1; i < 256; ++i) { b += i * hb[i]; g += i * hg[i]; r += i * hr[i]; } int alpha = sum / area; int div = area * 255; return ColorBgra.FromBgraClamped (b / div, g / div, r / div, alpha); } }
// This isn't really an extension method, since it doesn't use // the passed in argument, but it's nice to have the same calling // convention as the uncached version. If you can use this one // over the other, it is much faster in tight loops (like effects). public static unsafe ColorBgra GetPointUnchecked(this ImageSurface surf, ColorBgra* surfDataPtr, int surfWidth, int x, int y) { ColorBgra* dstPtr = surfDataPtr; dstPtr += (x) + (y * surfWidth); return *dstPtr; }
public unsafe override void Apply(ColorBgra *dst, ColorBgra *src, int length) { for (int i = 0; i < length; i++) { *dst = *src; dst++; src++; } }
public unsafe override void Apply(ColorBgra* dst, ColorBgra* src, int length) { while (length > 0) { *dst = setColor; ++dst; --length; } }
public HistogramRgb() : base(3, 256) { visualColors = new ColorBgra[]{ ColorBgra.Blue, ColorBgra.Green, ColorBgra.Red }; }
public unsafe void Render(Cairo.ImageSurface dst, Gdk.Point offset) { if (cr.ScaleFactor > new ScaleFactor (1, 2)) return; int[] d2SLookupX = cr.Dst2SrcLookupX; int[] d2SLookupY = cr.Dst2SrcLookupY; int[] s2DLookupX = cr.Src2DstLookupX; int[] s2DLookupY = cr.Src2DstLookupY; ColorBgra[] blackAndWhite = new ColorBgra[2] { ColorBgra.White, ColorBgra.Black }; // draw horizontal lines int dstHeight = dst.Height; int dstWidth = dst.Width; int dstStride = dst.Stride; int sTop = d2SLookupY[offset.Y]; int sBottom = d2SLookupY[offset.Y + dstHeight]; for (int srcY = sTop; srcY <= sBottom; ++srcY) { int dstY = s2DLookupY[srcY]; int dstRow = dstY - offset.Y; if (dstRow >= 0 && dstRow < dstHeight) { ColorBgra* dstRowPtr = dst.GetRowAddressUnchecked (dstRow); ColorBgra* dstRowEndPtr = dstRowPtr + dstWidth; dstRowPtr += offset.X & 1; while (dstRowPtr < dstRowEndPtr) { *dstRowPtr = ColorBgra.Black; dstRowPtr += 2; } } } // draw vertical lines int sLeft = d2SLookupX[offset.X]; int sRight = d2SLookupX[offset.X + dstWidth]; for (int srcX = sLeft; srcX <= sRight; ++srcX) { int dstX = s2DLookupX[srcX]; int dstCol = dstX - offset.X; if (dstCol >= 0 && dstCol < dstWidth) { byte* dstColPtr = (byte*)dst.GetPointAddress (dstCol, 0); byte* dstColEndPtr = dstColPtr + dstStride * dstHeight; dstColPtr += (offset.Y & 1) * dstStride; while (dstColPtr < dstColEndPtr) { *((ColorBgra*)dstColPtr) = ColorBgra.Black; dstColPtr += 2 * dstStride; } } } }
public unsafe override void Apply(ColorBgra* ptr, int length) { while (length > 0) { *ptr = setColor; ++ptr; --length; } }
public unsafe virtual void Apply(ColorBgra* ptr, int length) { unsafe { while (length > 0) { *ptr = Apply (*ptr); ++ptr; --length; } } }
public unsafe override void Apply(ColorBgra* dst, ColorBgra* src, int length) { unsafe { while (length > 0) { *dst = Apply (*src); ++dst; ++src; --length; } } }
public override ColorBgra Apply(ColorBgra color) { int a = blendColor.A; int invA = 255 - a; int r = ((color.R * invA) + (blendColor.R * a)) / 256; int g = ((color.G * invA) + (blendColor.G * a)) / 256; int b = ((color.B * invA) + (blendColor.B * a)) / 256; byte a2 = ComputeAlpha(color.A, blendColor.A); return ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, a2); }
public unsafe virtual void Apply (ColorBgra* dst, ColorBgra* lhs, ColorBgra* rhs, int length) { unsafe { while (length > 0) { *dst = Apply (*lhs, *rhs); ++dst; ++lhs; ++rhs; --length; } } }
public unsafe override ColorBgra Apply(ColorBgra src, int area, int* hb, int* hg, int* hr, int* ha) { int resultB = BlurChannel (src.B, hb); int resultG = BlurChannel (src.G, hg); int resultR = BlurChannel (src.R, hr); // there is no way we can deal with pre-multiplied alphas; the correlation // between channels no longer exists by this point in the algorithm... // so, just use the alpha from the source pixel. ColorBgra result = ColorBgra.FromBgra ((byte)resultB, (byte)resultG, (byte)resultR, src.A); return result; }
public ColorBgra Apply (ColorBgra color, int checkerX, int checkerY) { int b = color.B; int g = color.G; int r = color.R; int a = ApplyOpacity (color.A); int v = ((checkerX ^ checkerY) & 8) * 8 + 191; a = a + (a >> 7); int vmia = v * (256 - a); r = ((r * a) + vmia) >> 8; g = ((g * a) + vmia) >> 8; b = ((b * a) + vmia) >> 8; return ColorBgra.FromUInt32 ((uint)b + ((uint)g << 8) + ((uint)r << 16) + 0xff000000); }
public static unsafe void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance, out Rectangle boundingBox) { int top = int.MaxValue; int bottom = int.MinValue; int left = int.MaxValue; int right = int.MinValue; stencil.Clear (false); for (int y = 0; y < surface.Height; ++y) { bool foundPixelInRow = false; ColorBgra* ptr = surface.GetRowAddressUnchecked (y); for (int x = 0; x < surface.Width; ++x) { if (CheckColor (cmp, *ptr, tolerance)) { stencil.SetUnchecked (x, y, true); if (x < left) { left = x; } if (x > right) { right = x; } foundPixelInRow = true; } ++ptr; } if (foundPixelInRow) { if (y < top) { top = y; } if (y >= bottom) { bottom = y; } } } boundingBox = new Rectangle (left, top, right + 1, bottom + 1); }
private static unsafe ColorBgra GetPercentileOfColor (ColorBgra color, int area, int* hb, int* hg, int* hr, int* ha) { int rc = 0; int gc = 0; int bc = 0; for (int i = 0; i < color.R; ++i) rc += hr[i]; for (int i = 0; i < color.G; ++i) gc += hg[i]; for (int i = 0; i < color.B; ++i) bc += hb[i]; rc = (rc * 255) / area; gc = (gc * 255) / area; bc = (bc * 255) / area; return ColorBgra.FromBgr ((byte)bc, (byte)gc, (byte)rc); }
/// <summary> /// Smoothly blends between two colors. /// </summary> public static ColorBgra Blend(ColorBgra ca, ColorBgra cb, byte cbAlpha) { uint caA = (uint)Utility.FastScaleByteByByte((byte)(255 - cbAlpha), ca.A); uint cbA = (uint)Utility.FastScaleByteByByte(cbAlpha, cb.A); uint cbAT = caA + cbA; uint r; uint g; uint b; if (cbAT == 0) { r = 0; g = 0; b = 0; } else { r = ((ca.R * caA) + (cb.R * cbA)) / cbAT; g = ((ca.G * caA) + (cb.G * cbA)) / cbAT; b = ((ca.B * caA) + (cb.B * cbA)) / cbAT; } return ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)cbAT); }
/// <summary> /// Performs the actual work of rendering an effect. This overload represent a single pixel of the image. /// </summary> /// <param name="color">The color of the source surface pixel.</param> /// <returns>The color to be used for the destination pixel.</returns> protected virtual ColorBgra Render(ColorBgra color) { return(color); }
public abstract ColorBgra Apply(ColorBgra color);
private void DrawChannel(Context g, ColorBgra color, int channel, long max, float mean) { Rectangle rect = Allocation.ToCairoRectangle (); Histogram histogram = Histogram; int l = (int)rect.X; int t = (int)rect.Y; int r = (int)(rect.X + rect.Width); int b = (int)(rect.Y + rect.Height); int entries = histogram.Entries; long[] hist = histogram.HistogramValues [channel]; ++max; if (FlipHorizontal) { Utility.Swap(ref l, ref r); } if (!FlipVertical) { Utility.Swap(ref t, ref b); } PointD[] points = new PointD[entries + 2]; points[entries] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (t, b, 20)); points[entries + 1] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (b, t, 20)); for (int i = 0; i < entries; i += entries - 1) { points[i] = new PointD ( Utility.Lerp (l, r, (float)hist[i] / (float)max), Utility.Lerp (t, b, (float)i / (float)entries)); CheckPoint (rect, points [i]); } long sum3 = hist[0] + hist[1]; for (int i = 1; i < entries - 1; ++i) { sum3 += hist[i + 1]; points[i] = new PointD( Utility.Lerp(l, r, (float)(sum3) / (float)(max * 3.1f)), Utility.Lerp(t, b, (float)i / (float)entries)); CheckPoint (rect, points [i]); sum3 -= hist[i - 1]; } byte intensity = selected[channel] ? (byte)96 : (byte)32; ColorBgra pen_color = ColorBgra.Blend (ColorBgra.Black, color, intensity); ColorBgra brush_color = color; brush_color.A = intensity; g.LineWidth = 1; g.Rectangle (rect); g.Clip (); g.DrawPolygonal (points, pen_color.ToCairoColor ()); g.FillPolygonal (points, brush_color.ToCairoColor ()); }
private static void ComputeAlphaOnlyValuesFromColors(ColorBgra startColor, ColorBgra endColor, out byte startAlpha, out byte endAlpha) { startAlpha = startColor.A; endAlpha = (byte)(255 - endColor.A); }
public unsafe static void SetColorBgra(this Cairo.ImageSurface surf, ColorBgra *surfDataPtr, int surfWidth, ColorBgra color, int x, int y) { ColorBgra *dstPtr = surfDataPtr; dstPtr += (x) + (y * surfWidth); *dstPtr = color; }
public static int ColorDifference (ColorBgra a, ColorBgra b) { return (int)Math.Ceiling (Math.Sqrt (ColorDifferenceSquared (a, b))); }
public unsafe override ColorBgra Apply(ColorBgra src, int area, int* hb, int* hg, int* hr, int* ha) { int minCount1 = area * (100 - this.intensity) / 200; int minCount2 = area * (100 + this.intensity) / 200; int bCount = 0; int b1 = 0; while (b1 < 255 && hb[b1] == 0) ++b1; while (b1 < 255 && bCount < minCount1) { bCount += hb[b1]; ++b1; } int b2 = b1; while (b2 < 255 && bCount < minCount2) { bCount += hb[b2]; ++b2; } int gCount = 0; int g1 = 0; while (g1 < 255 && hg[g1] == 0) ++g1; while (g1 < 255 && gCount < minCount1) { gCount += hg[g1]; ++g1; } int g2 = g1; while (g2 < 255 && gCount < minCount2) { gCount += hg[g2]; ++g2; } int rCount = 0; int r1 = 0; while (r1 < 255 && hr[r1] == 0) ++r1; while (r1 < 255 && rCount < minCount1) { rCount += hr[r1]; ++r1; } int r2 = r1; while (r2 < 255 && rCount < minCount2) { rCount += hr[r2]; ++r2; } int aCount = 0; int a1 = 0; while (a1 < 255 && hb[a1] == 0) ++a1; while (a1 < 255 && aCount < minCount1) { aCount += ha[a1]; ++a1; } int a2 = a1; while (a2 < 255 && aCount < minCount2) { aCount += ha[a2]; ++a2; } return ColorBgra.FromBgra ( (byte)(255 - (b2 - b1)), (byte)(255 - (g2 - g1)), (byte)(255 - (r2 - r1)), (byte)(a2)); }
public static unsafe void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance, out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection) { int top = int.MaxValue; int bottom = int.MinValue; int left = int.MaxValue; int right = int.MinValue; Gdk.Rectangle[] scans; stencil.Clear (false); if (limitToSelection) { using (Gdk.Region excluded = Gdk.Region.Rectangle (new Gdk.Rectangle (0, 0, stencil.Width, stencil.Height))) { excluded.Xor (limitRegion); scans = excluded.GetRectangles (); } } else { scans = new Gdk.Rectangle[0]; } foreach (Gdk.Rectangle rect in scans) stencil.Set (rect, true); for (int y = 0; y < surface.Height; ++y) { bool foundPixelInRow = false; ColorBgra* ptr = surface.GetRowAddressUnchecked (y); for (int x = 0; x < surface.Width; ++x) { if (CheckColor (cmp, *ptr, tolerance)) { stencil.SetUnchecked (x, y, true); if (x < left) { left = x; } if (x > right) { right = x; } foundPixelInRow = true; } ++ptr; } if (foundPixelInRow) { if (y < top) { top = y; } if (y >= bottom) { bottom = y; } } } foreach (Gdk.Rectangle rect in scans) stencil.Set (rect, false); boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1); }
/// <summary> /// Returns a new ColorBgra with the same color values but with a new alpha component value. /// </summary> public ColorBgra NewAlpha(byte newA) { return(ColorBgra.FromBgra(B, G, R, newA)); }
private static void ComputeAlphaOnlyValuesFromColors(ColorBgra startColor, ColorBgra endColor, out byte startAlpha, out byte endAlpha) { startAlpha = startColor.A; endAlpha = (byte)(255 - endColor.A); }
public static unsafe ColorBgra GetBilinearSampleClamped(this ImageSurface src, ColorBgra *srcDataPtr, int srcWidth, int srcHeight, float x, float y) { if (!Utility.IsNumber(x) || !Utility.IsNumber(y)) { return(ColorBgra.Transparent); } float u = x; float v = y; if (u < 0) { u = 0; } else if (u > srcWidth - 1) { u = srcWidth - 1; } if (v < 0) { v = 0; } else if (v > srcHeight - 1) { v = srcHeight - 1; } unchecked { int iu = (int)Math.Floor(u); uint sxfrac = (uint)(256 * (u - (float)iu)); uint sxfracinv = 256 - sxfrac; int iv = (int)Math.Floor(v); uint syfrac = (uint)(256 * (v - (float)iv)); uint syfracinv = 256 - syfrac; uint wul = (uint)(sxfracinv * syfracinv); uint wur = (uint)(sxfrac * syfracinv); uint wll = (uint)(sxfracinv * syfrac); uint wlr = (uint)(sxfrac * syfrac); int sx = iu; int sy = iv; int sleft = sx; int sright; if (sleft == (srcWidth - 1)) { sright = sleft; } else { sright = sleft + 1; } int stop = sy; int sbottom; if (stop == (srcHeight - 1)) { sbottom = stop; } else { sbottom = stop + 1; } ColorBgra *cul = src.GetPointAddressUnchecked(srcDataPtr, srcWidth, sleft, stop); ColorBgra *cur = cul + (sright - sleft); ColorBgra *cll = src.GetPointAddressUnchecked(srcDataPtr, srcWidth, sleft, sbottom); ColorBgra *clr = cll + (sright - sleft); ColorBgra c = ColorBgra.BlendColors4W16IP(*cul, wul, *cur, wur, *cll, wll, *clr, wlr); return(c); } }
public static unsafe ColorBgra GetBilinearSampleWrapped(this ImageSurface src, ColorBgra *srcDataPtr, int srcWidth, int srcHeight, float x, float y) { if (!Utility.IsNumber(x) || !Utility.IsNumber(y)) { return(ColorBgra.Transparent); } float u = x; float v = y; unchecked { int iu = (int)Math.Floor(u); uint sxfrac = (uint)(256 * (u - (float)iu)); uint sxfracinv = 256 - sxfrac; int iv = (int)Math.Floor(v); uint syfrac = (uint)(256 * (v - (float)iv)); uint syfracinv = 256 - syfrac; uint wul = (uint)(sxfracinv * syfracinv); uint wur = (uint)(sxfrac * syfracinv); uint wll = (uint)(sxfracinv * syfrac); uint wlr = (uint)(sxfrac * syfrac); int sx = iu; if (sx < 0) { sx = (srcWidth - 1) + ((sx + 1) % srcWidth); } else if (sx > (srcWidth - 1)) { sx = sx % srcWidth; } int sy = iv; if (sy < 0) { sy = (srcHeight - 1) + ((sy + 1) % srcHeight); } else if (sy > (srcHeight - 1)) { sy = sy % srcHeight; } int sleft = sx; int sright; if (sleft == (srcWidth - 1)) { sright = 0; } else { sright = sleft + 1; } int stop = sy; int sbottom; if (stop == (srcHeight - 1)) { sbottom = 0; } else { sbottom = stop + 1; } ColorBgra cul = src.GetPointUnchecked(srcDataPtr, srcWidth, sleft, stop); ColorBgra cur = src.GetPointUnchecked(srcDataPtr, srcWidth, sright, stop); ColorBgra cll = src.GetPointUnchecked(srcDataPtr, srcWidth, sleft, sbottom); ColorBgra clr = src.GetPointUnchecked(srcDataPtr, srcWidth, sright, sbottom); ColorBgra c = ColorBgra.BlendColors4W16IP(cul, wul, cur, wur, cll, wll, clr, wlr); return(c); } }
public static ColorBgra ToBgraColor(this Gdk.Color color) { return(ColorBgra.FromBgr((byte)(color.Blue * 255 / ushort.MaxValue), (byte)(color.Green * 255 / ushort.MaxValue), (byte)(color.Red * 255 / ushort.MaxValue))); }
public static ColorBgra ParseHexString(string hexString) { uint value = Convert.ToUInt32(hexString, 16); return(ColorBgra.FromUInt32(value)); }
private int MaskAvg(ColorBgra before) { int count = 0, total = 0; for (int c = 0; c < 3; c++) { if (mask [c]) { total += before [c]; count++; } } if (count > 0) { return total / count; } else { return 0; } }
/// <summary> /// Blends four colors together based on the given weight values. /// </summary> /// <returns>The blended color.</returns> /// <remarks> /// The weights should be 16-bit fixed point numbers that add up to 65536 ("1.0"). /// 4W16IP means "4 colors, weights, 16-bit integer precision" /// </remarks> public static ColorBgra BlendColors4W16IP(ColorBgra c1, uint w1, ColorBgra c2, uint w2, ColorBgra c3, uint w3, ColorBgra c4, uint w4) { #if DEBUG if ((w1 + w2 + w3 + w4) != 65536) { throw new ArgumentOutOfRangeException("w1 + w2 + w3 + w4 must equal 65536!"); } #endif const uint ww = 32768; uint af = (c1.A * w1) + (c2.A * w2) + (c3.A * w3) + (c4.A * w4); uint a = (af + ww) >> 16; uint b; uint g; uint r; if (a == 0) { b = 0; g = 0; r = 0; } else { b = (uint)((((long)c1.A * c1.B * w1) + ((long)c2.A * c2.B * w2) + ((long)c3.A * c3.B * w3) + ((long)c4.A * c4.B * w4)) / af); g = (uint)((((long)c1.A * c1.G * w1) + ((long)c2.A * c2.G * w2) + ((long)c3.A * c3.G * w3) + ((long)c4.A * c4.G * w4)) / af); r = (uint)((((long)c1.A * c1.R * w1) + ((long)c2.A * c2.R * w2) + ((long)c3.A * c3.R * w3) + ((long)c4.A * c4.R * w4)) / af); } return(ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)a)); }
public static Gdk.Color ToGdkColor(this ColorBgra color) { Gdk.Color c = new Gdk.Color(color.R, color.G, color.B); return(c); }
// These methods are ported from PDN. private static bool CheckColor(ColorBgra a, ColorBgra b, int tolerance) { int sum = 0; int diff; diff = a.R - b.R; sum += (1 + diff * diff) * a.A / 256; diff = a.G - b.G; sum += (1 + diff * diff) * a.A / 256; diff = a.B - b.B; sum += (1 + diff * diff) * a.A / 256; diff = a.A - b.A; sum += diff * diff; return (sum <= tolerance * tolerance * 4); }
public static unsafe SurfaceDiff Create(ImageSurface original, ImageSurface updated_surf, bool force = false) { if (original.Width != updated_surf.Width || original.Height != updated_surf.Height) { // If the surface changed size, only throw an error if the user forced the use of a diff. if (force) { throw new InvalidOperationException("SurfaceDiff requires surfaces to be same size."); } else { return(null); } } // Cache some pinvokes var orig_width = original.Width; var orig_height = original.Height; #if DEBUG_DIFF Console.WriteLine("Original surface size: {0}x{1}", orig_width, orig_height); System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); #endif // STEP 1 - Find the bounds of the changed pixels. var orig_ptr = (int *)original.DataPtr; var updated_ptr = (int *)updated_surf.DataPtr; DiffBounds diff_bounds = new DiffBounds(orig_width, orig_height); object diff_bounds_lock = new Object(); // Split up the work among several threads, each of which processes one row at a time // and updates the bounds of the changed pixels it has seen so far. At the end, the // results from each thread are merged together to find the overall bounds of the changed // pixels. Parallel.For <DiffBounds>(0, orig_height, () => new DiffBounds(orig_width, orig_height), (row, loop, my_bounds) => { var offset = row * orig_width; var orig = orig_ptr + offset; var updated = updated_ptr + offset; bool change_in_row = false; for (int i = 0; i < orig_width; ++i) { if (*(orig++) != *(updated++)) { change_in_row = true; my_bounds.left = System.Math.Min(my_bounds.left, i); my_bounds.right = System.Math.Max(my_bounds.right, i); } } if (change_in_row) { my_bounds.top = System.Math.Min(my_bounds.top, row); my_bounds.bottom = System.Math.Max(my_bounds.bottom, row); } return(my_bounds); }, (my_bounds) => { lock (diff_bounds_lock) { diff_bounds.Merge(my_bounds); } return; }); var bounds = new Gdk.Rectangle(diff_bounds.left, diff_bounds.top, diff_bounds.right - diff_bounds.left + 1, diff_bounds.bottom - diff_bounds.top + 1); #if DEBUG_DIFF Console.WriteLine("Truncated surface size: {0}x{1}", bounds.Width, bounds.Height); #endif // STEP 2 - Create a bitarray of whether each pixel in the bounds has changed, and count // how many changed pixels we need to store. var bitmask = new BitArray(bounds.Width * bounds.Height); int index = 0; int num_changed = 0; int bottom = bounds.GetBottom(); int right = bounds.GetRight(); int bounds_x = bounds.X; int bounds_y = bounds.Y; for (int y = bounds_y; y <= bottom; ++y) { var offset = y * orig_width; var updated = updated_ptr + offset + bounds_x; var orig = orig_ptr + offset + bounds_x; for (int x = bounds_x; x <= right; ++x) { bool changed = *(orig++) != *(updated++); bitmask[index++] = changed; if (changed) { num_changed++; } } } var savings = 100 - (float)num_changed / (float)(orig_width * orig_height) * 100; #if DEBUG_DIFF Console.WriteLine("Compressed bitmask: {0}/{1} = {2}%", num_changed, orig_height * orig_width, 100 - savings); #endif if (!force && savings < MINIMUM_SAVINGS_PERCENT) { #if DEBUG_DIFF Console.WriteLine("Savings too small, returning null"); #endif return(null); } // Store the old pixels. var pixels = new ColorBgra[num_changed]; var new_ptr = (ColorBgra *)original.DataPtr; int mask_index = 0; fixed(ColorBgra *fixed_ptr = pixels) { var pixel_ptr = fixed_ptr; for (int y = bounds_y; y <= bottom; ++y) { var new_pixel_ptr = new_ptr + bounds_x + y * orig_width; for (int x = bounds_x; x <= right; ++x) { if (bitmask[mask_index++]) { *pixel_ptr++ = *new_pixel_ptr; } new_pixel_ptr++; } } } #if DEBUG_DIFF timer.Stop(); System.Console.WriteLine("SurfaceDiff time: " + timer.ElapsedMilliseconds); #endif return(new SurfaceDiff(bitmask, bounds, pixels)); }
public unsafe override ColorBgra Apply (ColorBgra src, int area, int* hb, int* hg, int* hr, int* ha) { ColorBgra c = GetPercentile (this.percentile, area, hb, hg, hr, ha); return c; }
private ColorBgra AdjustColorDifference(ColorBgra oldColor, ColorBgra newColor, ColorBgra basisColor) { ColorBgra returnColor; // eliminate testing for the "equal to" case returnColor = basisColor; returnColor.B = AdjustColorByte (oldColor.B, newColor.B, basisColor.B); returnColor.G = AdjustColorByte (oldColor.G, newColor.G, basisColor.G); returnColor.R = AdjustColorByte (oldColor.R, newColor.R, basisColor.R); return returnColor; }
private ColorBgra UpdateByMask(ColorBgra before, byte val) { ColorBgra after = before; int average = -1, oldaverage = -1; if (!(mask [0] || mask [1] || mask [2])) { return before; } do { float factor; oldaverage = average; average = MaskAvg (after); if (average == 0) { break; } factor = (float)val / average; for (int c = 0; c < 3; c++) { if (mask [c]) { after [c] = (byte)Utility.ClampToByte (after [c] * factor); } } } while (average != val && oldaverage != average); while (average != val) { average = MaskAvg (after); int diff = val - average; for (int c = 0; c < 3; c++) { if (mask [c]) { after [c] = (byte)Utility.ClampToByte(after [c] + diff); } } } after.A = 255; return after; }
private bool IsColorInTolerance(ColorBgra colorA, ColorBgra colorB) { return Utility.ColorDifference (colorA, colorB) <= myTolerance; }
public static int ColorDifferenceSquared (ColorBgra a, ColorBgra b) { int diffSq = 0, tmp; tmp = a.R - b.R; diffSq += tmp * tmp; tmp = a.G - b.G; diffSq += tmp * tmp; tmp = a.B - b.B; diffSq += tmp * tmp; return diffSq / 3; }
public abstract ColorBgra Apply(ColorBgra color);