diff --git a/src/main/java/com/github/romankh3/image/comparison/ImageComparison.java b/src/main/java/com/github/romankh3/image/comparison/ImageComparison.java index 8067c0b..c3996de 100644 --- a/src/main/java/com/github/romankh3/image/comparison/ImageComparison.java +++ b/src/main/java/com/github/romankh3/image/comparison/ImageComparison.java @@ -702,4 +702,64 @@ public ImageComparison setExcludedRectangleColor(Color excludedRectangleColor) { this.excludedRectangleColor = excludedRectangleColor; return this; } + + + /** + * compare images while ignore their position in background + * @param dest is the result destination + * @return the result of the drawing. + */ + public ImageComparisonResult compareImagesIgnoreBackground(File dest) { + int exceptedBgd = getBackgroundRGB(expected); + int actualBgd = getBackgroundRGB(actual); + BufferedImage expectedInterest = getInterestArea(expected, exceptedBgd); + BufferedImage actualInterest = getInterestArea(actual, actualBgd); + ImageComparison imageComparison = new ImageComparison(expectedInterest, actualInterest, dest); + return imageComparison.compareImages(); + } + + private int getBackgroundRGB(BufferedImage image) { + // count RGB + Map countMap = new HashMap<>(); + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + if (!excludedAreas.contains(new Point(x, y))) { + int key = image.getRGB(x, y); + if (countMap.containsKey(key)) { + countMap.put(key, countMap.get(key) + 1); + } else { + countMap.put(key, 1); + } + } + } + } + // get background + int backGround = Integer.MIN_VALUE; + int maxCount = Integer.MIN_VALUE; + for (Map.Entry entry : countMap.entrySet()) { + if (entry.getValue() > maxCount) { + maxCount = entry.getValue(); + backGround = entry.getKey(); + } + } + return backGround; + } + + private BufferedImage getInterestArea(BufferedImage image, int background) { + Point leftTop = new Point(image.getWidth(), image.getHeight()); + Point rightBottom = new Point(0, 0); + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + if (!excludedAreas.contains(new Point(x, y))) { + if (image.getRGB(x, y) != background){ + leftTop = new Point(Math.min(x, leftTop.x), Math.min(y, leftTop.y)); + rightBottom = new Point(Math.max(x, rightBottom.x), Math.max(y, rightBottom.y)); + } + } + } + } + return image.getSubimage(leftTop.x, leftTop.y, + rightBottom.x - leftTop.x, rightBottom.y - leftTop.y); + } + } diff --git a/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUnitTest.java b/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUnitTest.java index 73b9c49..f0b286d 100644 --- a/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUnitTest.java +++ b/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUnitTest.java @@ -523,6 +523,63 @@ public void shouldProperlyCompareMisSizedImages() { assertTrue(differenceLessThan2); } + @DisplayName("Should properly compare while ignore white background for #217") + @Test + public void shouldProperlyHandelIssue217() { + //given + BufferedImage expected = readImageFromResources("expected#217a.png"); + BufferedImage actual = readImageFromResources("actual#217a.png"); + BufferedImage expectedResult = readImageFromResources("result#217a.png"); + + //when + ImageComparisonResult imageComparisonResult = + new ImageComparison(expected, actual) + .setPixelToleranceLevel(0.0) + .compareImagesIgnoreBackground(null); + + //then + assertEquals(MISMATCH, imageComparisonResult.getImageComparisonState()); + assertImagesEqual(expectedResult, imageComparisonResult.getResult()); + } + + + @DisplayName("Should properly compare while ignore white background for #217") + @Test + public void shouldProperlyCompareIgnoreBackground() { + //given + BufferedImage expected = readImageFromResources("expected#217b.png"); + BufferedImage actual = readImageFromResources("actual#217b.png"); + + //when + ImageComparisonResult imageComparisonResult = + new ImageComparison(expected, actual) + .setPixelToleranceLevel(0.0) + .compareImagesIgnoreBackground(null); + + //then + assertEquals(MATCH, imageComparisonResult.getImageComparisonState()); + } + + @DisplayName("Should properly compare difference while ignore background") + @Test + public void shouldProperlyCompareDifferenceAndIgnoreBackground() { + //given + BufferedImage expected = readImageFromResources("expected#217c.png"); + BufferedImage actual = readImageFromResources("actual#217c.png"); + BufferedImage expectedResult = readImageFromResources("result#217c.png"); + + //when + ImageComparisonResult imageComparisonResult = + new ImageComparison(expected, actual) + .setPixelToleranceLevel(0.0) + .compareImagesIgnoreBackground(null); + + //then + assertEquals(MISMATCH, imageComparisonResult.getImageComparisonState()); + assertImagesEqual(expectedResult, imageComparisonResult.getResult()); + } + + private void assertImagesEqual(BufferedImage expected, BufferedImage actual) { if (expected.getWidth() != actual.getWidth() || expected.getHeight() != actual.getHeight()) { fail("Images have different dimensions"); diff --git a/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUtilUnitTest.java b/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUtilUnitTest.java index 9f2a2e9..7e83359 100644 --- a/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUtilUnitTest.java +++ b/src/test/java/com/github/romankh3/image/comparison/ImageComparisonUtilUnitTest.java @@ -160,7 +160,7 @@ public void shouldProperlyWorkInBug136() { @Test public void shouldProperlyHandleBug180FromRoot() { //given - String imagePath = "build/resources/test/result.png"; + String imagePath = "build/test-images/result.png"; //when BufferedImage result = ImageComparisonUtil.readImageFromResources(imagePath); diff --git a/src/test/resources/actual#217a.png b/src/test/resources/actual#217a.png new file mode 100644 index 0000000..8eb6bb4 Binary files /dev/null and b/src/test/resources/actual#217a.png differ diff --git a/src/test/resources/actual#217b.png b/src/test/resources/actual#217b.png new file mode 100644 index 0000000..22f5ecf Binary files /dev/null and b/src/test/resources/actual#217b.png differ diff --git a/src/test/resources/actual#217c.png b/src/test/resources/actual#217c.png new file mode 100644 index 0000000..75036ef Binary files /dev/null and b/src/test/resources/actual#217c.png differ diff --git a/src/test/resources/expected#217a.png b/src/test/resources/expected#217a.png new file mode 100644 index 0000000..1b0edfb Binary files /dev/null and b/src/test/resources/expected#217a.png differ diff --git a/src/test/resources/expected#217b.png b/src/test/resources/expected#217b.png new file mode 100644 index 0000000..ab36571 Binary files /dev/null and b/src/test/resources/expected#217b.png differ diff --git a/src/test/resources/expected#217c.png b/src/test/resources/expected#217c.png new file mode 100644 index 0000000..f0671c5 Binary files /dev/null and b/src/test/resources/expected#217c.png differ diff --git a/src/test/resources/result#217a.png b/src/test/resources/result#217a.png new file mode 100644 index 0000000..e5ee9ec Binary files /dev/null and b/src/test/resources/result#217a.png differ diff --git a/src/test/resources/result#217c.png b/src/test/resources/result#217c.png new file mode 100644 index 0000000..57668a8 Binary files /dev/null and b/src/test/resources/result#217c.png differ