/** * Merges another image onto the base image (to the right) * * @param mergeImage the image to be merged * @param position where to locate the newly merged image * @return this */ @NotNull public ImageOverlayBuilder mergeImage(@NotNull BufferedImage mergeImage, @NotNull MergeImagesFilter.Position position) { MergeImagesFilter mergeImagesFilter = new MergeImagesFilter(mergeImage, SMALL_PADDING, position); bufferedImage = mergeImagesFilter.applyFilter(bufferedImage); return this; }
/** * Apply a title to the base image. * * @param location where to locate the title. * @param font the font to use. * @param color the color * @param text the title * @return this */ @NotNull public ImageOverlayBuilder titleImage(PointLocations location, Font font, @NotNull CognitiveJColourPalette color, @NotNull String text) { ApplyCaptionOutsideImageFilter applyCaptionOutsideImageFilter = new ApplyCaptionOutsideImageFilter(location, font, color, text); bufferedImage = applyCaptionOutsideImageFilter.applyFilter(bufferedImage); return this; }
@NotNull @Override public BufferedImage applyFilter(@NotNull BufferedImage bufferedImage) { Graphics2D graphics2D = bufferedImage.createGraphics(); imageGrownBy = calculateGrowth(); GrowImageFilter growImageFilter = new GrowImageFilter(imageGrownBy); BufferedImage grownImage = growImageFilter.applyFilter(bufferedImage); int height = calculateHeight(); ImageCaptionFilter imageCaptionFilter = new ImageCaptionFilter(location, OverlayUtils.calculateMaxFontForString(graphics2D, font, grownImage.getWidth() - magicPadding, height, text), color.getBackground(), text, 10); graphics2D.dispose(); return imageCaptionFilter.applyFilter(grownImage); }
/** * Draws a verification graphic for the base image and the passed image. * * @param candidateImage - the passed image. * @param verificationSet - a verification set to be drawn. * @return this */ @NotNull public ImageOverlayBuilder verify(@NotNull BufferedImage candidateImage, @NotNull VerificationSet verificationSet) { CognitiveJColourPalette verificationColor = verificationSet.getVerification().isIdentical ? CognitiveJColourPalette.GREEN : CognitiveJColourPalette.RED; outlineFaceOnImage(verificationSet.getFirstFace(), RectangleType.CORNERED, BorderWeight.THICK, verificationColor); OverlayRectangleFilter overlayRectangleFilter = new OverlayRectangleFilter(verificationSet.getSecondFace().faceRectangle.asAwtRectangle(), RectangleType.CORNERED, BorderWeight.THICK, verificationColor); MergeImagesFilter mergeImagesFilter = new MergeImagesFilter(overlayRectangleFilter.applyFilter(candidateImage), SMALL_PADDING, MergeImagesFilter.Position.RIGHT); LineJoinRectangleFilter lineJoinRectangleFilter = new LineJoinRectangleFilter(verificationSet.getFirstFace().faceRectangle.asAwtRectangle(), verificationSet.getSecondFace().faceRectangle.asAwtRectangle(), BorderWeight.THICK, verificationColor, bufferedImage.getWidth(), SMALL_PADDING); Verification verification = verificationSet.getVerification(); ApplyCaptionOutsideImageFilter applyCaptionOutsideImageFilter = new ApplyCaptionOutsideImageFilter(PointLocations.BOTTOM_CENTER, DEFAULT_TEXT_FONT.deriveFont(80f).deriveFont(80f), verificationColor, verification.isIdentical ? String.format("Match (confidence %.3f)", verification.confidence) : String.format("No Match (confidence %.3f)", verification.confidence)); bufferedImage = applyCaptionOutsideImageFilter.applyFilter(lineJoinRectangleFilter.applyFilter(mergeImagesFilter.applyFilter(bufferedImage))); return this; }
private void applyText(Graphics2D graphics2D) { graphics2D.setFont(requestedFont); graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); int availableWidthForTextContainer = boundedTextContainerWidth(graphics2D); setupFontWidth(graphics2D, availableWidthForTextContainer); int availableHeightForTextContainer = boundedTextContainerHeight(graphics2D); setupFontHeight(graphics2D, availableWidthForTextContainer, availableHeightForTextContainer); int startingX = calculateTextContainerStartingPointX(availableWidthForTextContainer); int startingY = calculateTextContainerStartingPointY(baseRectangle, availableHeightForTextContainer, rectangleTextPosition); Rectangle textContainer = new Rectangle(startingX, startingY, availableWidthForTextContainer, availableHeightForTextContainer); drawOutliningRectangle(graphics2D, textContainer, cognitiveJColourPalette.getBackground()); applyTextOver(graphics2D, textContainer); }
@NotNull @Override public BufferedImage applyFilter(@NotNull BufferedImage bufferedImage) { BufferedImage newImage = createNewBufferedImage(calculateNewWidth(bufferedImage), calculateNewHeight(bufferedImage), bufferedImage.getType()); Graphics2D graphics2D = newImage.createGraphics(); graphics2D.drawImage(bufferedImage, existingImageX(bufferedImage), existingImageY(bufferedImage), null); graphics2D.drawImage(mergeImage, newImageX(bufferedImage), newImageY(bufferedImage), null); graphics2D.dispose(); return newImage; }
@NotNull private ImageOverlayBuilder outlineOCRWord(@NotNull OCRResult.Word word) { OverlayRectangleFilter overlayRectangleFilter = new OverlayRectangleFilter(word.boundingBoxAsAwtRectangle(), RectangleType.FULL, BorderWeight.THINNER, CognitiveJColourPalette.randomColour()); TextOnRectangleFilter textOnRectangleFilter = new TextOnRectangleFilter(new Rectangle(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight()), word.boundingBoxAsAwtRectangle(), new Insets(0, 0, 0, 0), new Font("Noto Sans", Font.PLAIN, 12), CognitiveJColourPalette.TRANS_GRAY, RectangleTextPosition.BOTTOM_OF, word.text); bufferedImage = textOnRectangleFilter.applyFilter(overlayRectangleFilter.applyFilter(bufferedImage)); return this; }
@NotNull @Override public BufferedImage applyFilter(@NotNull BufferedImage bufferedImage) { Graphics2D graphics2D = bufferedImage.createGraphics(); graphics2D.setColor(color.getBackground()); graphics2D.setStroke(new BasicStroke(lineThickness.thickness())); Point leftRectangleBottom = new Point(rectangle1.x + rectangle1.width, rectangle1.y + rectangle1.height); Point leftRectangleTop = new Point(rectangle1.x + rectangle1.width, rectangle1.y); Point rightRectangleTop = new Point(rectangle2.x + xOffset, rectangle2.y + insets.top); Point rightRectangleBottom = new Point(rectangle2.x + xOffset, rectangle2.y + insets.top + rectangle2.height); PointDistance pointDistance = calculatePoints(leftRectangleTop, leftRectangleBottom, rightRectangleTop, rightRectangleBottom); graphics2D.drawLine(pointDistance.getLeftPoint().x, pointDistance.getLeftPoint().y, pointDistance.getRightPoint().x, pointDistance.getRightPoint().y); graphics2D.dispose(); return bufferedImage; }
@NotNull public ImageOverlayBuilder outlineFaceOnImage(@NotNull Face face, @NotNull RectangleType rectangleType, @NotNull BorderWeight borderWeight, @NotNull CognitiveJColourPalette colourPalette) { OverlayRectangleFilter overlayRectangleFilter = new OverlayRectangleFilter(face.faceRectangle.asAwtRectangle(), rectangleType, borderWeight, colourPalette); bufferedImage = overlayRectangleFilter.applyFilter(bufferedImage); return this; }
private PointDistance calculatePoints(Point leftRectangleTop, Point leftRectangleBottom, Point rightRectangleTop, Point rightRectangleBottom) { PointDistance distance1 = new PointDistance(leftRectangleTop, rightRectangleTop); PointDistance distance2 = new PointDistance(leftRectangleBottom, rightRectangleTop); PointDistance distance3 = new PointDistance(leftRectangleTop, rightRectangleBottom); PointDistance distance4 = new PointDistance(leftRectangleTop, rightRectangleBottom); java.util.List<PointDistance> pointDistances = Arrays.asList(distance1, distance2, distance3, distance4); Collections.sort(pointDistances, (o1, o2) -> Double.compare(o1.getDistance(), o2.getDistance())); return pointDistances.get(0); }
/** * Outlines a face on the base image with defaults; * ({@link ImageOverlayBuilder#outlineFaceOnImage(Face, RectangleType, BorderWeight, CognitiveJColourPalette)} * * @param face - the face. * @return this */ @NotNull public ImageOverlayBuilder pixelateFaceOnImage(@NotNull Face face) { PixelatedImageSectionFilter pixelatedImageSectionFilter = new PixelatedImageSectionFilter(face.faceRectangle.asAwtRectangle()); bufferedImage = pixelatedImageSectionFilter.applyFilter(bufferedImage); return this; }
private int boundedTextContainerWidth(Graphics2D graphics2D) { switch (rectangleTextPosition) { case LEFT_OF: return Math.max(baseRectangle.width, graphics2D.getFontMetrics().stringWidth(maxSingleLineStringWidth(text))); case RIGHT_OF: return Math.min(fullImageDimension.width - (baseRectangle.x + baseRectangle.width + insets.right + insets.left), baseRectangle.width); case TOP_OF: /**fall through to RIGHT_OF"&**/ case BOTTOM_OF: return baseRectangle.width; } return 0; }
private int boundedTextContainerHeight(Graphics2D graphics2D) { switch (rectangleTextPosition) { case LEFT_OF: /**fall through to RIGHT_OF**/ case RIGHT_OF: return Math.min(Math.max(graphics2D.getFontMetrics().getHeight() + (insets.top / 2), baseRectangle.height) * rowsInString(), baseRectangle.height); case TOP_OF: return (graphics2D.getFontMetrics().getHeight() + insets.top / 2) * rowsInString(); case BOTTOM_OF: return (graphics2D.getFontMetrics().getHeight() + insets.top / 2) * rowsInString(); } return 0; }
@NotNull @Override public BufferedImage applyFilter(@NotNull BufferedImage bufferedImage) { Graphics2D graphics2D = bufferedImage.createGraphics(); applyText(graphics2D); graphics2D.dispose(); return bufferedImage; }
@NotNull @Override public BufferedImage applyFilter(@NotNull BufferedImage bufferedImage) { BufferedImage newImage = createNewBufferedImage(bufferedImage.getWidth() + insets.left+ insets.right, bufferedImage.getHeight() + insets.top+ insets.bottom, bufferedImage.getType()); Graphics2D graphics2D = newImage.createGraphics(); graphics2D.drawImage(bufferedImage, insets.left, insets.top, null); graphics2D.dispose(); return newImage; }
private static void buildGrid(ImageOverlayBuilder imageOverlayBuilder, People people) { ImageGrid candidates = new ImageGrid(extractImagesFromPeople(people), 4); ApplyCaptionOutsideImageFilter applyCaptionOutsideImageFilter = new ApplyCaptionOutsideImageFilter(PointLocations.TOP_CENTER, ImageOverlayBuilder.DEFAULT_TEXT_FONT, CognitiveJColourPalette.WHITE, "Candidate Dataset"); BufferedImage mergeImage = applyCaptionOutsideImageFilter.applyFilter(candidates.build()); imageOverlayBuilder.mergeImage(mergeImage); }
/** * Draw the rectangle and outline the dominant @{@link Emotion} * * @param emotion the emotion * @param textPosition where the text is to be positioned * @return this */ @NotNull public ImageOverlayBuilder outlineDominantEmotionOnImage(@NotNull Emotion emotion, @NotNull RectangleTextPosition textPosition) { OverlayRectangleFilter overlayRectangleFilter = new OverlayRectangleFilter(emotion.faceRectangle.asAwtRectangle(), RectangleType.CORNERED, DEFAULT_BORDER_WEIGHT, CognitiveJColourPalette.STRAWBERRY); TextOnRectangleFilter textOnRectangleFilter = new TextOnRectangleFilter(new Rectangle(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight()), emotion.faceRectangle.asAwtRectangle(), new Insets(0, 0, 0, 0), DEFAULT_TEXT_FONT, CognitiveJColourPalette.STRAWBERRY, textPosition, EmotionStringBuilder.dominantEmotion(emotion)); bufferedImage = textOnRectangleFilter.applyFilter(overlayRectangleFilter.applyFilter(bufferedImage)); return this; }
@NotNull private ImageOverlayBuilder outlineOCRLine(OCRResult.Line line) { OverlayRectangleFilter overlayRectangleFilter = new OverlayRectangleFilter(line.boundingBoxAsAwtRectangle(), RectangleType.FULL, BorderWeight.THINNER, CognitiveJColourPalette.randomColour()); bufferedImage = overlayRectangleFilter.applyFilter(bufferedImage); line.words.forEach(this::outlineOCRWord); return this; }
private void setupFontWidth(Graphics2D graphics2D, int textContainerWidth) { float fontSize = requestedFont.getSize(); FontRenderContext fontRenderContext = graphics2D.getFontRenderContext(); Rectangle2D bounds = requestedFont.getStringBounds(maxSingleLineStringWidth(text), fontRenderContext); while (bounds.getWidth() > textContainerWidth - (insets.left + insets.right)) { requestedFont = requestedFont.deriveFont((fontSize -= 2)); bounds = requestedFont.getStringBounds(maxSingleLineStringWidth(text), fontRenderContext); } graphics2D.setFont(requestedFont); }
private void setupFontHeight(Graphics2D graphics2D, int textContainerWidth, int maxHeightOfText) { float fontSize = requestedFont.getSize(); FontRenderContext fontRenderContext = graphics2D.getFontRenderContext(); Rectangle2D bounds = requestedFont.getStringBounds(maxSingleLineStringWidth(text), fontRenderContext); while (bounds.getWidth() > textContainerWidth || bounds.getHeight() > maxHeightOfText) { requestedFont = requestedFont.deriveFont((fontSize -= 2)); bounds = requestedFont.getStringBounds(maxSingleLineStringWidth(text), fontRenderContext); } graphics2D.setFont(requestedFont); }