def compareUnequal(image1, image2, numberOfRequiredUnequalPixels, percentageOfRGBDifferenceRequiredPerPixel): log.info("Requiring {}% difference on RGBA value per pixel, and require {} really distinct pixels".format(percentageOfRGBDifferenceRequiredPerPixel*100, numberOfRequiredUnequalPixels)) if not _checkImageSizeEqual(image1, image2): return False nrEqualPixels = 0 nrTooSimilarPixels = 0 totalNumberOfPixels = image1.width * image1.height # PIL image comparison is well optimized -> early out if images are identical if image1 == image2: nrEqualPixels = totalNumberOfPixels nrTooSimilarPixels = totalNumberOfPixels else: imageDiff = ImageChops.difference(image1.convert("RGBA"), image2.convert("RGBA")) imageData = imageDiff.getdata() percentageOfRGBDifferenceRequiredPerPixelScaled = int(percentageOfRGBDifferenceRequiredPerPixel*255) for i in range(0, image1.width * image1.height): chMax = max(imageData[i]) if chMax < percentageOfRGBDifferenceRequiredPerPixelScaled: nrTooSimilarPixels += 1 if chMax == 0: nrEqualPixels += 1 log.important_info("Comparison stats: Percentage of too similar pixels: {}% ({})".format(float(nrTooSimilarPixels) / totalNumberOfPixels*100, nrTooSimilarPixels)) log.important_info("Comparison stats: Percentage of exactly equal pixels: {}% ({})".format(float(nrEqualPixels) / totalNumberOfPixels*100, nrEqualPixels)) if totalNumberOfPixels - nrTooSimilarPixels < numberOfRequiredUnequalPixels: log.error("compareUnequal: Not enough unequal pixels, aborting...") return False return True
def take_screenshot_and_compare(self, renderer, imageName, testClassName, testRunName, displayNumber, screenshotNumber, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel, numberOfRequiredUnequalPixels, useSystemCompositorForScreenshot, compareForEquality): log.info("taking screenshot...") referenceImagePath = self._find_reference_image(imageName) refImage = Image.open(referenceImagePath) minWidth = refImage.size[0] minHeight = refImage.size[1] pathToResultScreenshot = self._take_and_transfer_screenshot(renderer, imageName, screenshotNumber, testClassName, testRunName, displayNumber, useSystemCompositorForScreenshot, minWidth, minHeight) if not os.path.isfile(pathToResultScreenshot): log.errorAndAssert("Screenshot not found at {}".format(pathToResultScreenshot)) else: log.info("comparing images...") if (self.percentageOfRGBDifferenceAllowedPerPixelOnTarget > percentageOfRGBDifferenceAllowedPerPixel): log.important_info("Allowing higher difference per pixel because of target value: {}%".format(self.percentageOfRGBDifferenceAllowedPerPixelOnTarget*100)) percentageOfRGBDifferenceAllowedPerPixel = self.percentageOfRGBDifferenceAllowedPerPixelOnTarget if (self.percentageOfWrongPixelsAllowedOnTarget > percentageOfWrongPixelsAllowed): log.important_info("Allowing higher number of wrong pixels because of target value: {}%".format(self.percentageOfWrongPixelsAllowedOnTarget*100)) percentageOfWrongPixelsAllowed = self.percentageOfWrongPixelsAllowedOnTarget helper.compare_images(pathToResultScreenshot, referenceImagePath, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel, numberOfRequiredUnequalPixels, self.imageDiffScaleFactor, compareForEquality)
def compareEqual(image1, image2, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel): log.info("Allowing {}% tolerance on RGBA value per pixel, and {}% wrong pixels".format(percentageOfRGBDifferenceAllowedPerPixel*100, percentageOfWrongPixelsAllowed*100)) if not _checkImageSizeEqual(image1, image2): return False nrWrongPixels = 0 nrDifferentPixels = 0 # PIL image comparison is well optimized -> early out if images are identical if image1 != image2: imageDiff = ImageChops.difference(image1.convert("RGBA"), image2.convert("RGBA")) imageData = imageDiff.getdata() percentageOfRGBDifferenceAllowedPerPixelScaled = int(percentageOfRGBDifferenceAllowedPerPixel*255) for i in range(0, image1.width * image1.height): chMax = max(imageData[i]) if chMax > 0: nrDifferentPixels += 1 if chMax > percentageOfRGBDifferenceAllowedPerPixelScaled: nrWrongPixels += 1 totalNumberOfPixels = image1.width * image1.height log.important_info("Comparison stats: Percentage of wrong pixels: {0}%".format(float(nrWrongPixels) / totalNumberOfPixels*100)) log.important_info("Comparison stats: Percentage of different, but accepted pixels: {0}%".format(float(nrDifferentPixels-nrWrongPixels) / totalNumberOfPixels*100)) if ((float(nrWrongPixels) / totalNumberOfPixels) > percentageOfWrongPixelsAllowed): log.error("compareEqual: Too many wrong pixels, aborting...") return False return True
def compareUnequal(image1, image2, numberOfRequiredUnequalPixels, percentageOfRGBDifferenceRequiredPerPixel): log.info("compareUnequal: Bitmap compare of {0} with {1}".format( image1.filename, image2.filename)) log.info( "Requiring {}% difference on RGB value per pixel, and require {} really distinct pixels" .format(percentageOfRGBDifferenceRequiredPerPixel * 100, numberOfRequiredUnequalPixels)) if not _checkImageSizeEqual(image1, image2): return False # work around crappy nested function variable access rules nrEqualPixels = [0] nrTooSimilarPixels = [0] def compare(x, y, c1, c2, diff): if all(e < percentageOfRGBDifferenceRequiredPerPixel for e in diff): if nrTooSimilarPixels[0] == 0: log.info( "First wrong Pixel {}/{} (source pixel {} / otherPixel {})" .format(x, y, c1, c2)) nrTooSimilarPixels[0] += 1 if all(e == 0 for e in diff): nrEqualPixels[0] += 1 _forAllPixels(image1, image2, compare) totalNumberOfPixels = image1.size[0] * image1.size[1] log.important_info( "Comparison stats: Percentage of too similar pixels: {}% ({})".format( float(nrTooSimilarPixels[0]) / totalNumberOfPixels * 100, nrTooSimilarPixels[0])) log.important_info( "Comparison stats: Percentage of exactly equal pixels: {}% ({})". format( float(nrEqualPixels[0]) / totalNumberOfPixels * 100, nrEqualPixels[0])) if totalNumberOfPixels - nrTooSimilarPixels[ 0] < numberOfRequiredUnequalPixels: log.error("compareUnequal: Not enough unequal pixels, aborting...") return False return True
def compareEqual(image1, image2, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel): log.info("compareEqual: Bitmap compare of {0} with {1}".format( image1.filename, image2.filename)) log.info( "Allowing {}% tolerance on RGB value per pixel, and {}% wrong pixels". format(percentageOfRGBDifferenceAllowedPerPixel * 100, percentageOfWrongPixelsAllowed * 100)) if not _checkImageSizeEqual(image1, image2): return False # work around nested function variable access rules nrWrongPixels = [0] nrDifferentPixels = [0] def compare(x, y, c1, c2, diff): if any(e > 0 for e in diff): nrDifferentPixels[0] += 1 if any(e > percentageOfRGBDifferenceAllowedPerPixel for e in diff): if nrWrongPixels[0] == 0: log.info( "First wrong Pixel {}/{} (source pixel {} / otherPixel {})" .format(x, y, c1, c2)) nrWrongPixels[0] += 1 _forAllPixels(image1, image2, compare) totalNumberOfPixels = image1.size[0] * image1.size[1] log.important_info( "Comparison stats: Percentage of wrong pixels: {0}%".format( float(nrWrongPixels[0]) / totalNumberOfPixels * 100)) log.important_info( "Comparison stats: Percentage of different, but accepted pixels: {0}%". format( float(nrDifferentPixels[0] - nrWrongPixels[0]) / totalNumberOfPixels * 100)) if ((float(nrWrongPixels[0]) / totalNumberOfPixels) > percentageOfWrongPixelsAllowed): log.error("compareEqual: Too many wrong pixels, aborting...") return False return True
def compareUnequal(image1, image2, numberOfRequiredUnequalPixels, percentageOfRGBDifferenceRequiredPerPixel): log.info( "Requiring {}% difference on RGB value per pixel, and require {} really distinct pixels" .format(percentageOfRGBDifferenceRequiredPerPixel * 100, numberOfRequiredUnequalPixels)) if not _checkImageSizeEqual(image1, image2): return False # work around crappy nested function variable access rules nrEqualPixels = [0] nrTooSimilarPixels = [0] def compare(c1, c2, diff): if all(e < percentageOfRGBDifferenceRequiredPerPixel for e in diff): nrTooSimilarPixels[0] += 1 if all(e == 0 for e in diff): nrEqualPixels[0] += 1 totalNumberOfPixels = image1.width * image1.height if image1 == image2: # PIL image comparison is well optimized -> early out if images are identical nrEqualPixels = totalNumberOfPixels nrTooSimilarPixels = totalNumberOfPixels else: _forAllPixels(image1, image2, compare) log.important_info( "Comparison stats: Percentage of too similar pixels: {}% ({})".format( float(nrTooSimilarPixels[0]) / totalNumberOfPixels * 100, nrTooSimilarPixels[0])) log.important_info( "Comparison stats: Percentage of exactly equal pixels: {}% ({})". format( float(nrEqualPixels[0]) / totalNumberOfPixels * 100, nrEqualPixels[0])) if totalNumberOfPixels - nrTooSimilarPixels[ 0] < numberOfRequiredUnequalPixels: log.error("compareUnequal: Not enough unequal pixels, aborting...") return False return True
def compareEqual(image1, image2, percentageOfWrongPixelsAllowed, percentageOfRGBDifferenceAllowedPerPixel): log.info( "Allowing {}% tolerance on RGB value per pixel, and {}% wrong pixels". format(percentageOfRGBDifferenceAllowedPerPixel * 100, percentageOfWrongPixelsAllowed * 100)) if not _checkImageSizeEqual(image1, image2): return False # work around nested function variable access rules nrWrongPixels = [0] nrDifferentPixels = [0] def compare(c1, c2, diff): if any(e > 0 for e in diff): nrDifferentPixels[0] += 1 if any(e > percentageOfRGBDifferenceAllowedPerPixel for e in diff): nrWrongPixels[0] += 1 if image1 != image2: # PIL image comparison is well optimized -> early out if images are identical _forAllPixels(image1, image2, compare) totalNumberOfPixels = image1.width * image1.height log.important_info( "Comparison stats: Percentage of wrong pixels: {0}%".format( float(nrWrongPixels[0]) / totalNumberOfPixels * 100)) log.important_info( "Comparison stats: Percentage of different, but accepted pixels: {0}%". format( float(nrDifferentPixels[0] - nrWrongPixels[0]) / totalNumberOfPixels * 100)) if ((float(nrWrongPixels[0]) / totalNumberOfPixels) > percentageOfWrongPixelsAllowed): log.error("compareEqual: Too many wrong pixels, aborting...") return False return True