avh4 / imagecomparison

Tools for comparing images and writing image-based approval tests. This library is published on Maven Central.
8 stars 4 forks source link

Compare two images directly #8

Open javatlacati opened 4 years ago

javatlacati commented 4 years ago

For your LooksLikeMatcher you should always provide a file.

I'd like it to have the option to provide just a BufferedImage object.

javatlacati commented 4 years ago

I have this code as a sample:

package com.toedter.matchers;

import com.toedter.util.ImageDifferentiator;
import net.avh4.util.imagecomparison.ImageComparison;
import net.avh4.util.imagecomparison.ImageComparisonResult;
import org.hamcrest.Description;
import org.hamcrest.DiagnosingMatcher;
import org.hamcrest.Matcher;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

public class DirectImageLooksLikeMatcher extends DiagnosingMatcher<Object> {

    private final BufferedImage referenceImage;
    private final Dimension referenceImageSize;

    private DirectImageLooksLikeMatcher(BufferedImage referenceImage, Dimension referenceImageSize) {
        this.referenceImage = referenceImage;
        this.referenceImageSize = referenceImageSize;
    }

    protected boolean matches(Object item, Description mismatchDescription) {
        ImageComparisonResult result = ImageComparison.compare(item, this.referenceImage);
        if (result.isEqual()) {
            return true;
        } else if (this.referenceImage == null) {
            mismatchDescription.appendText("approval image ");
            mismatchDescription.appendText(" doesn't exist -- expected to find it in ");
            return false;
        } else {
            mismatchDescription.appendText("images don't match: ");
            mismatchDescription.appendText(result.getFailureMessage());
            try {
                File imagesDir = new File(System.getProperty("differingImagesFolder"));
                if (!imagesDir.exists()) {
                    imagesDir.mkdir();
                }
                Random r = new Random();
                String fileName = imagesDir + "/comparisionFailed"+r.nextInt(12383)+".png";
                System.out.println("diff image should be created at " + fileName);
                ImageDifferentiator.createDiffImage(referenceImage, (BufferedImage) item, fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
    }

    public void describeTo(Description description) {
        if (this.referenceImage == null) {
            description.appendText("reference image to exist");
        } else {
            description.appendText(String.format("something that looks like (%dx%d)", this.referenceImageSize.width, this.referenceImageSize.height));
        }

    }

    public static Matcher<Object> looksLike(BufferedImage referenceImage, Dimension referenceImageSize) {
        return new DirectImageLooksLikeMatcher(referenceImage, referenceImageSize);
    }
}
Shryne commented 4 years ago

The author of this project doesn't work on it anymore as mentioned in #6. However, as far as I remember it isn't that difficult to fork the project and change it so that you can provide image files. Unfortunately, there are some hard dependencies, meaning that you will have to change large parts of the code.

It's not hard, just a lot of typing.