All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.catools.media.utils.CImageComparisionUtil Maven / Gradle / Ivy

package org.catools.media.utils;

import boofcv.struct.image.GrayF32;
import org.apache.commons.lang3.NotImplementedException;
import org.catools.common.collections.CList;
import org.catools.common.exception.CRuntimeException;
import org.catools.common.io.CFile;
import org.catools.common.io.CResource;
import org.catools.media.enums.CImageComparisonType;
import org.catools.media.model.CDiffPoint;
import org.catools.media.model.CDiffPoints;
import org.testng.Assert;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Objects;

import static org.catools.media.utils.CImageUtil.writePNG;

public class CImageComparisionUtil {
    /**
     * Compare 2 images and return difference.
     * We use bootcv library here to convert image to flat gray with one bound to improve match algorithm.
     *
     * @param comparisonType CImageComparisonType value which defines comparison type.
     * @param img1           first image to compare
     * @param img2           second image to compare
     * @param diff           file to save diff in png format
     * @return {@link CDiffPoints} contains list of diff, empty if not diff found
     */
    public static CDiffPoints getDiffs(BufferedImage img1, BufferedImage img2, CFile diff, CImageComparisonType comparisonType) {
        CDiffPoints diffs = getDiffs(img1, img2, comparisonType);

        if (diffs == null || diffs.isEmpty()) {
            return new CDiffPoints();
        }
        return drawDiffImage(diff, diffs, img1);
    }

    /**
     * Compare 2 images and return difference.
     * We use bootcv library here to convert image to flat gray with one bound to improve match algorithm.
     *
     * @param img1           first image to compare
     * @param img2           second image to compare
     * @param comparisonType CImageComparisonType value which defines comparison type.
     * @return {@link CDiffPoints} contains list of diff, empty if not diff found
     */
    public static CDiffPoints getDiffs(BufferedImage img1, BufferedImage img2, CImageComparisonType comparisonType) {
        switch (comparisonType) {
            case GRAY_FLOAT_32:
                return getGrayF32Diffs(img1, img2);
            case FULL_COLOR:
                return getDiffs(img1, img2);
            default:
                throw new NotImplementedException("There is no implementation in CImageSimpleComparator for type of " + comparisonType);
        }
    }

    private static CDiffPoints getGrayF32Diffs(BufferedImage img1, BufferedImage img2) {
        Objects.requireNonNull(img1);
        Objects.requireNonNull(img2);

        GrayF32 grayImg1 = CBoofCVUtil.toGrayF32(img1);
        GrayF32 grayImg2 = CBoofCVUtil.toGrayF32(img2);

        CBoofCVUtil.reshapeToSameSize(grayImg1, grayImg2);

        CDiffPoints diffs = new CDiffPoints();
        for (int x = 0; x < grayImg1.getWidth(); x++) {
            for (int y = 0; y < grayImg1.getHeight(); y++) {
                if (Math.abs(grayImg1.get(x, y) - grayImg2.get(x, y)) > 5) {
                    diffs.add(new CDiffPoint(x, y, img1.getRGB(x, y), img1.getRGB(x, y)));
                }
            }
        }
        return diffs;
    }

    private static CDiffPoints getDiffs(BufferedImage img1, BufferedImage img2) {
        Objects.requireNonNull(img1);
        Objects.requireNonNull(img2);

        Assert.assertEquals(img1.getHeight(), img2.getHeight(), "Both image have a same Height.");
        Assert.assertEquals(img1.getWidth(), img2.getWidth(), "Both image have a same Width.");

        CDiffPoints diffs = new CDiffPoints();
        for (int x = 0; x < img1.getWidth(); x++) {
            for (int y = 0; y < img1.getHeight(); y++) {
                if (Math.abs(img1.getRGB(x, y) - img2.getRGB(x, y)) > 5) {
                    diffs.add(new CDiffPoint(x, y, img1.getRGB(x, y), img1.getRGB(x, y)));
                }
            }
        }
        return diffs;
    }

    private static CDiffPoints drawDiffImage(final CFile diff, final CDiffPoints diffs, final BufferedImage img1) {
        BufferedImage bufferedImage = new BufferedImage(img1.getWidth(), img1.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = bufferedImage.createGraphics();
        graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.03f));
        graphics.drawImage(img1, 0, 0, null);
        graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));

        for (CDiffPoint r : diffs) {
            graphics.setColor(new Color(r.getDiffColor()));
            graphics.drawLine(r.x, r.y, r.x, r.y);
        }
        graphics.dispose();
        writePNG(bufferedImage, diff);
        return diffs;
    }

    public static CList toBufferedImageList(Iterable input) {
        CList output = new CList<>();
        for (Object o : input) {
            if (o instanceof File) {
                output.add(CImageUtil.readImage((File) o));
            } else if (o instanceof CResource) {
                output.add(CImageUtil.readImage((CResource) o));
            } else if (o instanceof BufferedImage) {
                output.add((BufferedImage) o);
            } else if (o == null) {
                output.add(null);
            } else {
                throw new CRuntimeException("Expected list can contains only File, CResource and BufferedImage values. Current record is " + o);
            }
        }
        return output;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy