public static uint ComputeAbsDiff(PixelElement Test, PixelElement Ref) { int R = Math.Abs((int)Test.r - (int)Ref.r); int G = Math.Abs((int)Test.g - (int)Ref.g); int B = Math.Abs((int)Test.b - (int)Ref.b); return((uint)Math.Max(R, Math.Max(G, B))); }
/* * public void SetErrorColor(float squaredError) * { * a = 0xff; * * if (squaredError > 0.0f) * { * // no error is black, minor error is a noticeable color * squaredError += 800; * } * squaredError /= 8; * * r = (byte)(Math.Min(0xff, squaredError)); * g = (byte)(Math.Min(0xff, squaredError / 8)); * b = (byte)(Math.Min(0xff, squaredError / 64)); * } */ public static float ComputeSquaredError(PixelElement Test, PixelElement Ref) { float R = (float)Test.r - (float)Ref.r; float G = (float)Test.g - (float)Ref.g; float B = (float)Test.b - (float)Ref.b; return(R * R + G * G + B * B); }
public static uint ComputeAbsDiff(PixelElement Test, PixelElement Ref) { int R = Math.Abs((int)Test.r - (int)Ref.r); int G = Math.Abs((int)Test.g - (int)Ref.g); int B = Math.Abs((int)Test.b - (int)Ref.b); return (uint)Math.Max(R, Math.Max(G, B)); }
/* public void SetErrorColor(float squaredError) { a = 0xff; if (squaredError > 0.0f) { // no error is black, minor error is a noticeable color squaredError += 800; } squaredError /= 8; r = (byte)(Math.Min(0xff, squaredError)); g = (byte)(Math.Min(0xff, squaredError / 8)); b = (byte)(Math.Min(0xff, squaredError / 64)); } */ public static float ComputeSquaredError(PixelElement Test, PixelElement Ref) { float R = (float)Test.r - (float)Ref.r; float G = (float)Test.g - (float)Ref.g; float B = (float)Test.b - (float)Ref.b; return R * R + G * G + B * B; }
// compute imageDiff from imageTest and imageRef public TestResult ComputeDiff(uint Threshold) { if (imageDiff != null) { imageDiff.Dispose(); imageDiff = null; } TestResult Ret = new TestResult(); if (imageTest == null) { Ret.ErrorText = "missing Test"; return(Ret); } if (imageRef == null) { Ret.ErrorText = "missing Ref"; return(Ret); } System.Drawing.Size sizeTest = GetImageSize(imageTest); System.Drawing.Size sizeRef = GetImageSize(imageRef); if (sizeTest != sizeRef) { Ret.ErrorText = "Size " + sizeTest.Width.ToString() + "x" + sizeTest.Height.ToString() + " != " + sizeRef.Width.ToString() + "x" + sizeRef.Height.ToString(); return(Ret); } System.Drawing.Size size = GetImagesSize(); // todo: exit if Size or format is not the same Debug.Assert(imageTest.PixelFormat == PixelFormat.Format32bppArgb); imageDiff = new Bitmap(size.Width, size.Height); uint CountedErrorPixels = 0; BitmapData dataTest = imageTest.LockBits(new Rectangle(0, 0, size.Width, size.Height), ImageLockMode.ReadOnly, imageTest.PixelFormat); BitmapData dataDiff = imageDiff.LockBits(new Rectangle(0, 0, size.Width, size.Height), ImageLockMode.WriteOnly, imageTest.PixelFormat); BitmapData dataRef = imageRef.LockBits(new Rectangle(0, 0, size.Width, size.Height), ImageLockMode.ReadOnly, imageTest.PixelFormat); unsafe { for (int x = 0; x < size.Width; ++x) { for (int y = 0; y < size.Height; ++y) { PixelElement *valueTest = (PixelElement *)((byte *)dataTest.Scan0.ToPointer() + dataTest.Stride * y + x * sizeof(PixelElement)); PixelElement *valueDiff = (PixelElement *)((byte *)dataDiff.Scan0.ToPointer() + dataDiff.Stride * y + x * sizeof(PixelElement)); PixelElement *valueRef = (PixelElement *)((byte *)dataRef.Scan0.ToPointer() + dataRef.Stride * y + x * sizeof(PixelElement)); // float Diff = PixelElement.ComputeSquaredError(*valueDiff, *valueRef); uint localError = PixelElement.ComputeAbsDiff(*valueTest, *valueRef); // all pixels opaque valueDiff->a = 0xff; if (localError >= Threshold) { ++CountedErrorPixels; // valueDiff->SetErrorColor(PixelElement.ComputeSquaredError(*valueTest, *valueRef)); valueDiff->SetErrorColor(localError); // *valueDiff = *valueRef; } } } } imageRef.UnlockBits(dataRef); imageDiff.UnlockBits(dataDiff); imageTest.UnlockBits(dataTest); Ret.ErrorPixels = CountedErrorPixels; // update Thumbnails { Ret.ThumbnailTest = resizeImage(imageTest); Ret.ThumbnailDiff = resizeImage(imageDiff); Ret.ThumbnailRef = resizeImage(imageRef); } return(Ret); }