package at.laborg.briss.model; import at.laborg.briss.gui.DrawableCropRect; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public final class SplitFinder { private final static double LOOK_RATIO = 0.5; private final static double MAX_DIST_RATIO = 0.1; private final static float ROW_OVERLAP_RATIO = 0.01f; private SplitFinder() { } private static Float getSplitRatio(final BufferedImage image, int axis) { WritableRaster raster = image.getRaster(); double[] sdOfDerivationX = ImageFinderUtil.createSdOfDerivation(raster, axis); int width = image.getWidth(); int rangeStart = (int) Math.floor(width * (LOOK_RATIO - MAX_DIST_RATIO / 2)); int rangeEnd = (int) Math.ceil(width * (LOOK_RATIO + MAX_DIST_RATIO / 2)); double min = Double.MAX_VALUE; int minIndex = -1; for (int i = rangeStart; i < rangeEnd; i++) { if (sdOfDerivationX[i] < min) { min = sdOfDerivationX[i]; minIndex = i; } } return ((float) minIndex) / width; } public static List<Float[]> splitColumn(final BufferedImage image, Float[] crop) { // TODO: Split within crop rect (currently finds split position on global preview image) float columnRatio = SplitFinder.getSplitRatio(image, ImageFinderUtil.X_AXIS); float width = 1 - crop[2] - crop[0]; float divider = crop[0] + columnRatio * width; return Arrays.asList( new Float[]{crop[0], crop[1], 1 - divider, crop[3]}, new Float[]{divider, crop[1], crop[2], crop[3]} ); } public static List<DrawableCropRect> splitColumn(final BufferedImage image, DrawableCropRect crop) { Float[] cropFloat = convertToFloatArray(image, crop); List<Float[]> split = splitColumn(image, cropFloat); ArrayList<DrawableCropRect> result = new ArrayList<>(split.size()); for (Float[] splitFloat : split) { result.add(convertToDrawableCropRect(image, splitFloat)); } return result; } public static List<Float[]> splitRow(final BufferedImage image, Float[] crop) { // TODO: Split within crop rect (currently finds split position on global preview image) float rowRatio = SplitFinder.getSplitRatio(image, ImageFinderUtil.Y_AXIS); float height = 1 - crop[1] - crop[3]; float divider = crop[3] + rowRatio * height; return Arrays.asList( new Float[]{crop[0], 1 - divider - ROW_OVERLAP_RATIO, crop[2], crop[3]}, new Float[]{crop[0], crop[1], crop[2], divider - ROW_OVERLAP_RATIO} ); } public static List<DrawableCropRect> splitRow(final BufferedImage image, DrawableCropRect crop) { Float[] cropFloat = convertToFloatArray(image, crop); List<Float[]> split = splitRow(image, cropFloat); ArrayList<DrawableCropRect> result = new ArrayList<>(split.size()); for (Float[] splitFloat : split) { result.add(convertToDrawableCropRect(image, splitFloat)); } return result; } private static Float[] convertToFloatArray(final BufferedImage image, DrawableCropRect crop) { float width = image.getWidth(); float height = image.getHeight(); return new Float[]{ crop.x / width, 1 - (crop.y + crop.height) / height, 1 - (crop.x + crop.width) / width, crop.y / height }; } private static DrawableCropRect convertToDrawableCropRect(final BufferedImage image, Float[] crop) { float width = image.getWidth(); float height = image.getHeight(); DrawableCropRect rect = new DrawableCropRect(); rect.setLocation((int) (crop[0] * width), (int) (crop[3] * height)); rect.setSize((int) ((1 - crop[0] - crop[2]) * width), (int) ((1 - crop[1] - crop[3]) * height)); return rect; } }