Here you can find the source of markDifferencesWithBoxes(final BufferedImage image, final Point[] pixels, final int markingSizeX, final int markingSizeY)
Parameter | Description |
---|---|
image | the original image for which the differences were found |
pixels | the array with the differences. |
markingSizeX | Length of the marker on the x axis |
markingSizeY | Length of the marker on the y axis |
protected static BufferedImage markDifferencesWithBoxes(final BufferedImage image, final Point[] pixels, final int markingSizeX, final int markingSizeY)
//package com.java2s; //License from project: Open Source License import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.image.BufferedImage; public class Main { /**/*from w w w . ja va2 s. c om*/ * Method to mark areas around the detected differences. Goes through every pixel that was different and marks the * marking block it is in, unless it was marked already. <br> * If markingX of markingY are 1, it will simply mark the detected differences. * * @param image the original image for which the differences were found * @param pixels * the array with the differences. * @param markingSizeX Length of the marker on the x axis * @param markingSizeY Length of the marker on the y axis * @return Copy of the original image with marked pixels */ protected static BufferedImage markDifferencesWithBoxes(final BufferedImage image, final Point[] pixels, final int markingSizeX, final int markingSizeY) { if (pixels == null) { return null; } final BufferedImage copy = copyImage(image); // Check if markingX or markingY are 1. If they are, just mark every // different pixel, // don't bother with rectangles if (markingSizeX == 1 || markingSizeY == 1) { for (final Point pixel : pixels) { colorPixel(copy, pixel.x, pixel.y, null); } return copy; } final int imageWidth = copy.getWidth(); final int imageHeight = copy.getHeight(); // And if markingX and markingY are above one, paint rectangles! // Normal case final int blocksX = imageWidth / markingSizeX; final int blocksY = imageHeight / markingSizeY; final boolean[][] markedBlocks = new boolean[blocksX + 1][blocksY + 1]; int xBlock, yBlock, subImageWidth, subImageHeight; for (final Point pixel : pixels) { xBlock = pixel.x / markingSizeX; yBlock = pixel.y / markingSizeY; subImageWidth = calcBlockLength(markingSizeX, xBlock, imageWidth); subImageHeight = calcBlockLength(markingSizeY, yBlock, imageHeight); if (!markedBlocks[xBlock][yBlock]) { drawBorders(copy, xBlock, yBlock, markingSizeX, markingSizeY, subImageWidth, subImageHeight, null); markedBlocks[xBlock][yBlock] = true; } } return copy; } /** * Creates another image, which is a copy of the source image * * @param source * the image to copy * @return a copy of that image as <b>BufferedImage</b> */ protected static BufferedImage copyImage(final BufferedImage source) { // Creates a fresh BufferedImage that has the same size and content of // the source image // if source has an image type of 0 set ARGB as type int imageType = source.getType(); if (imageType == 0) { imageType = BufferedImage.TYPE_INT_ARGB; } final BufferedImage copy = new BufferedImage(source.getWidth(), source.getHeight(), imageType); final Graphics g = copy.getGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); return copy; } /** * Colors a certain pixel using getComplementaryColor. Works directly on imgOut. * * @param x * the x coordinate of the pixel to color * @param y * the y coordinate of the pixel to color */ protected static void colorPixel(final BufferedImage image, final int x, final int y, final Color c) { Color newColor; if (c == null) { final Color currentColor = new Color(image.getRGB(x, y)); final double redLimit = 0.8; final int nonRedSum = currentColor.getGreen() + currentColor.getBlue(); final double results = nonRedSum > 0 ? currentColor.getRed() / nonRedSum : 0; if (results > redLimit) { // red is strong in that one newColor = Color.GREEN; } else { newColor = Color.RED; } } else { newColor = c; } image.setRGB(x, y, newColor.getRGB()); } /** * Calculates whether the current block exceeds either the x or y coordinates of the image. * Checks one axis of the image at a time. * * @param axisPixelCount * The number of pixels in this block for axis that should be checked * @param n * index of the current block * @param imageSpan * the width/ height of the image * @return The number of pixels that can be used for the mask either in the x or y axis */ protected static int calcBlockLength(final int axisPixelCount, final int n, final int imageSpan) { if (axisPixelCount * (n + 1) > imageSpan) { return imageSpan % axisPixelCount; } return axisPixelCount; } /** * Colors the borders of a certain rectangle. Used to mark blocks. Uses the colorPixel method and subImageHeight/ * subImageWidth. <br> * Works directly on imgOut. * * @param image * The image in which something will be marked * @param currentX * Starting position * @param currentY * Starting position * @param width * Vertical length of the rectangle to mark * @param height * Horizontal length of the rectangle to mark * @param subImageWidth the width of the partial image * @param subImageHeight the height of the partial image */ protected static void drawBorders(final BufferedImage image, final int currentX, final int currentY, final int width, final int height, final int subImageWidth, final int subImageHeight, final Color c) { int x, y; for (int a = 0; a < subImageWidth; a++) { x = currentX * width + a; y = currentY * height; colorPixel(image, x, y, c); y = currentY * height + subImageHeight - 1; colorPixel(image, x, y, c); } for (int b = 1; b < subImageHeight - 1; b++) { x = currentX * width; y = currentY * height + b; colorPixel(image, x, y, c); x = currentX * width + subImageWidth - 1; colorPixel(image, x, y, c); } } }