package ru.yandex.qatools.ashot.cropper.indent; import ru.yandex.qatools.ashot.Screenshot; import ru.yandex.qatools.ashot.coordinates.Coords; import ru.yandex.qatools.ashot.cropper.DefaultCropper; import ru.yandex.qatools.ashot.util.ImageTool; import java.awt.*; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; import static ru.yandex.qatools.ashot.coordinates.Coords.setReferenceCoords; /** * @author <a href="pazone@yandex-team.ru">Pavel Zorin</a> */ public class IndentCropper extends DefaultCropper { public static final int DEFAULT_INDENT = 50; private int indent = DEFAULT_INDENT; protected List<IndentFilter> filters = new LinkedList<>(); public IndentCropper(final int indent) { this.indent = indent; } public IndentCropper() { this(DEFAULT_INDENT); } @Override public Screenshot cropScreenshot(BufferedImage image, Set<Coords> coordsToCompare) { Coords cropArea = createCropArea(coordsToCompare); Coords indentMask = createIndentMask(cropArea, image); Coords coordsWithIndent = applyIndentMask(cropArea, indentMask); Screenshot croppedShot = super.cropScreenshot(image, Collections.singleton(coordsWithIndent)); croppedShot.setOriginShift(coordsWithIndent); croppedShot.setCoordsToCompare(setReferenceCoords(coordsWithIndent, coordsToCompare)); List<NoFilteringArea> noFilteringAreas = createNotFilteringAreas(croppedShot); croppedShot.setImage(applyFilters(croppedShot.getImage())); pasteAreasToCompare(croppedShot.getImage(), noFilteringAreas); return croppedShot; } protected Coords applyIndentMask(Coords origin, Coords mask) { Coords spreadCoords = new Coords(0, 0); spreadCoords.x = origin.x - mask.x; spreadCoords.y = origin.y - mask.y; spreadCoords.height = mask.y + origin.height + mask.height; spreadCoords.width = mask.x + origin.width + mask.width; return spreadCoords; } protected Coords createIndentMask(Coords originCoords, BufferedImage image) { Coords indentMask = new Coords(originCoords); indentMask.x = Math.min(indent, originCoords.x); indentMask.y = Math.min(indent, originCoords.y); indentMask.width = Math.min(indent, image.getWidth() - originCoords.x - originCoords.width); indentMask.height = Math.min(indent, image.getHeight() - originCoords.y - originCoords.height); return indentMask; } protected List<NoFilteringArea> createNotFilteringAreas(Screenshot screenshot) { List<NoFilteringArea> noFilteringAreas = new ArrayList<>(); for (Coords noFilteringCoords : screenshot.getCoordsToCompare()) { if (noFilteringCoords.intersects(Coords.ofImage(screenshot.getImage()))) { noFilteringAreas.add(new NoFilteringArea(screenshot.getImage(), noFilteringCoords)); } } return noFilteringAreas; } protected void pasteAreasToCompare(BufferedImage filtered, List<NoFilteringArea> noFilteringAreas) { Graphics graphics = filtered.getGraphics(); for (NoFilteringArea noFilteringArea : noFilteringAreas) { graphics.drawImage( noFilteringArea.getSubimage(), noFilteringArea.getCoords().x, noFilteringArea.getCoords().y, null); } graphics.dispose(); } public IndentCropper addIndentFilter(IndentFilter filter) { this.filters.add(filter); return this; } protected BufferedImage applyFilters(BufferedImage image) { for (IndentFilter filter : filters) { image = filter.apply(image); } return image; } private static class NoFilteringArea { private BufferedImage subimage; private Coords coords; private NoFilteringArea(BufferedImage origin, Coords noFilterCoords) { this.subimage = ImageTool.subImage(origin, noFilterCoords); this.coords = noFilterCoords; } public BufferedImage getSubimage() { return subimage; } public Coords getCoords() { return coords; } } }