Example usage for java.awt RenderingHints VALUE_ANTIALIAS_ON

List of usage examples for java.awt RenderingHints VALUE_ANTIALIAS_ON

Introduction

In this page you can find the example usage for java.awt RenderingHints VALUE_ANTIALIAS_ON.

Prototype

Object VALUE_ANTIALIAS_ON

To view the source code for java.awt RenderingHints VALUE_ANTIALIAS_ON.

Click Source Link

Document

Antialiasing hint value -- rendering is done with antialiasing.

Usage

From source file:net.java.sip.communicator.impl.osdependent.jdic.SystrayServiceJdicImpl.java

private BufferedImage createOverlayImage(String text) {
    int size = 16;
    BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = image.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    //background//ww  w.  java 2  s. c om
    g.setPaint(new Color(0, 0, 0, 102));
    g.fillRoundRect(0, 0, size, size, size, size);

    //filling
    int mainRadius = 14;
    g.setPaint(new Color(255, 98, 89));
    g.fillRoundRect(size / 2 - mainRadius / 2, size / 2 - mainRadius / 2, mainRadius, mainRadius, size, size);

    //text
    Font font = g.getFont();
    g.setFont(new Font(font.getName(), Font.BOLD, 9));
    FontMetrics fontMetrics = g.getFontMetrics();
    int textWidth = fontMetrics.stringWidth(text);
    g.setColor(Color.white);
    g.drawString(text, size / 2 - textWidth / 2,
            size / 2 - fontMetrics.getHeight() / 2 + fontMetrics.getAscent());

    return image;
}

From source file:business.ImageManager.java

private void doDrawPathOrdemArmy(Graphics2D big, Point ori, Point dest, Color color) {
    //setup para os rastros
    big.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    big.setComposite(alcom);//from   w  w  w .j  a va 2s .  co m
    big.setStroke(new BasicStroke(3f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1f,
            new float[] { 3f, 5f, 7f, 5f, 11f, 5f, 15f, 5f, 21f, 5f, 27f, 5f, 33f, 5f }, 0f));
    big.setColor(color);
    //draw path
    Path2D.Double path = new Path2D.Double();
    path.moveTo(ori.getX(), ori.getY());
    path.curveTo(dest.getX() + 10, dest.getY() - 10, dest.getX() - 10, dest.getY() + 10, dest.getX(),
            dest.getY());

    //draw on graph
    big.draw(path);
}

From source file:org.apache.batchee.tools.maven.doc.DiagramGenerator.java

private void saveView(final Dimension currentSize, final Dimension desiredSize, final String name,
        final VisualizationViewer<Node, Edge> viewer) {
    BufferedImage bi = new BufferedImage(currentSize.width, currentSize.height, BufferedImage.TYPE_INT_ARGB);

    final Graphics2D g = bi.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

    final boolean db = viewer.isDoubleBuffered();
    viewer.setDoubleBuffered(false);/*from   ww w.j a  v  a 2 s .com*/
    viewer.paint(g);
    viewer.setDoubleBuffered(db);
    if (!currentSize.equals(desiredSize)) {
        final double xFactor = desiredSize.width * 1. / currentSize.width;
        final double yFactor = desiredSize.height * 1. / currentSize.height;
        final double factor = Math.min(xFactor, yFactor);
        info("optimal size is (" + currentSize.width + ", " + currentSize.height + ")");
        info("scaling with a factor of " + factor);

        final AffineTransform tx = new AffineTransform();
        tx.scale(factor, factor);
        final AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
        BufferedImage biNew = new BufferedImage((int) (bi.getWidth() * factor), (int) (bi.getHeight() * factor),
                bi.getType());
        bi = op.filter(bi, biNew);
    }
    g.dispose();

    OutputStream os = null;
    try {
        final File file = new File(output, (outputFileName != null ? outputFileName : name) + "." + format);
        os = new FileOutputStream(file);
        if (!ImageIO.write(bi, format, os)) {
            throw new IllegalStateException("can't save picture " + name + "." + format);
        }
        info("Saved " + file.getAbsolutePath());
    } catch (final IOException e) {
        throw new IllegalStateException("can't save the diagram", e);
    } finally {
        if (os != null) {
            try {
                os.flush();
                os.close();
            } catch (final IOException e) {
                // no-op
            }
        }
    }
}

From source file:org.apache.batchee.tools.maven.DiagramMojo.java

private void saveView(final Dimension currentSize, final Dimension desiredSize, final String name,
        final VisualizationViewer<Node, Edge> viewer) throws MojoExecutionException {
    BufferedImage bi = new BufferedImage(currentSize.width, currentSize.height, BufferedImage.TYPE_INT_ARGB);

    final Graphics2D g = bi.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

    final boolean db = viewer.isDoubleBuffered();
    viewer.setDoubleBuffered(false);/*from   w ww .  j a v a2s . c  o  m*/
    viewer.paint(g);
    viewer.setDoubleBuffered(db);
    if (!currentSize.equals(desiredSize)) {
        final double xFactor = desiredSize.width * 1. / currentSize.width;
        final double yFactor = desiredSize.height * 1. / currentSize.height;
        final double factor = Math.min(xFactor, yFactor);
        getLog().info("optimal size is (" + currentSize.width + ", " + currentSize.height + ")");
        getLog().info("scaling with a factor of " + factor);

        final AffineTransform tx = new AffineTransform();
        tx.scale(factor, factor);
        final AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
        BufferedImage biNew = new BufferedImage((int) (bi.getWidth() * factor), (int) (bi.getHeight() * factor),
                bi.getType());
        bi = op.filter(bi, biNew);
    }
    g.dispose();

    OutputStream os = null;
    try {
        final File file = new File(output, (outputFileName != null ? outputFileName : name) + "." + format);
        os = new FileOutputStream(file);
        if (!ImageIO.write(bi, format, os)) {
            throw new MojoExecutionException("can't save picture " + name + "." + format);
        }
        getLog().info("Saved " + file.getAbsolutePath());
    } catch (final IOException e) {
        throw new MojoExecutionException("can't save the diagram", e);
    } finally {
        if (os != null) {
            try {
                os.flush();
                os.close();
            } catch (final IOException e) {
                // no-op
            }
        }
    }
}

From source file:business.ImageManager.java

private void doDrawPathOrdem(Graphics2D big, Point ori, Point dest, Color color) {
    //setup para os rastros
    big.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    big.setStroke(new BasicStroke(1.75f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1f,
            new float[] { 3f, 5f, 7f, 5f, 11f, 5f, 15f, 5f, 21f, 5f, 27f, 5f, 33f, 5f }, 0f));
    big.setColor(color);/*  ww w .  j  ava2  s .  c om*/
    //draw path
    Path2D.Double path = new Path2D.Double();
    path.moveTo(ori.getX(), ori.getY());
    path.curveTo(dest.getX() - 20, dest.getY() + 20, dest.getX() + 20, dest.getY() - 20, dest.getX() + 12,
            dest.getY());
    //path.lineTo(dest.getX(), dest.getY());

    //draw on graph
    big.draw(path);
}

From source file:org.executequery.gui.erd.ErdTable.java

protected void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    drawTable(g2d, 0, 0);//from  w  ww  .j av  a 2 s  . c  o m
}

From source file:savant.view.tracks.BAMTrackRenderer.java

/**
 * Render the individual bases on top of the read. Depending on the drawing
 * mode this can be either bases read or mismatches.
 *//*  w  w  w  .jav  a  2  s  .c  o m*/
private void renderBases(Graphics2D g2, GraphPaneAdapter gp, SAMRecord samRecord, int level, byte[] refSeq,
        Range range, double unitHeight) {

    ColourScheme cs = (ColourScheme) instructions.get(DrawingInstruction.COLOUR_SCHEME);

    boolean baseQualityEnabled = (Boolean) instructions.get(DrawingInstruction.BASE_QUALITY);
    boolean drawingAllBases = lastMode == DrawingMode.SEQUENCE || baseQualityEnabled;

    double unitWidth = gp.getUnitWidth();
    int offset = gp.getOffset();

    // Cutoffs to determine when not to draw
    double leftMostX = gp.transformXPos(range.getFrom());
    double rightMostX = gp.transformXPos(range.getTo()) + unitWidth;

    int alignmentStart = samRecord.getAlignmentStart();

    byte[] readBases = samRecord.getReadBases();
    byte[] baseQualities = samRecord.getBaseQualities();
    boolean sequenceSaved = readBases.length > 0;
    Cigar cigar = samRecord.getCigar();

    // Absolute positions in the reference sequence and the read bases, set after each cigar operator is processed
    int sequenceCursor = alignmentStart;
    int readCursor = alignmentStart;
    List<Rectangle2D> insertions = new ArrayList<Rectangle2D>();

    FontMetrics fm = g2.getFontMetrics(MISMATCH_FONT);
    Rectangle2D charRect = fm.getStringBounds("G", g2);
    boolean fontFits = charRect.getWidth() <= unitWidth && charRect.getHeight() <= unitHeight;
    if (fontFits) {
        g2.setFont(MISMATCH_FONT);
    }
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    for (CigarElement cigarElement : cigar.getCigarElements()) {

        int operatorLength = cigarElement.getLength();
        CigarOperator operator = cigarElement.getOperator();
        Rectangle2D.Double opRect = null;

        double opStart = gp.transformXPos(sequenceCursor);
        double opWidth = operatorLength * unitWidth;

        // Cut off start and width so no drawing happens off-screen, must be done in the order w, then x, since w depends on first value of x
        double x2 = Math.min(rightMostX, opStart + opWidth);
        opStart = Math.max(leftMostX, opStart);
        opWidth = x2 - opStart;

        switch (operator) {
        case D: // Deletion
            if (opWidth > 0.0) {
                renderDeletion(g2, gp, opStart, level, operatorLength, unitHeight);
            }
            break;

        case I: // Insertion
            insertions.add(new Rectangle2D.Double(gp.transformXPos(sequenceCursor),
                    gp.transformYPos(0) - ((level + 1) * unitHeight) - gp.getOffset(), unitWidth, unitHeight));
            break;

        case M: // Match or mismatch
        case X:
        case EQ:
            // some SAM files do not contain the read bases
            if (sequenceSaved || operator == CigarOperator.X) {
                for (int i = 0; i < operatorLength; i++) {
                    // indices into refSeq and readBases associated with this position in the cigar string
                    int readIndex = readCursor - alignmentStart + i;
                    boolean mismatched = false;
                    if (operator == CigarOperator.X) {
                        mismatched = true;
                    } else {
                        int refIndex = sequenceCursor + i - range.getFrom();
                        if (refIndex >= 0 && refSeq != null && refIndex < refSeq.length) {
                            mismatched = refSeq[refIndex] != readBases[readIndex];
                        }
                    }

                    if (mismatched || drawingAllBases) {
                        Color col;
                        if ((mismatched && lastMode != DrawingMode.STANDARD)
                                || lastMode == DrawingMode.SEQUENCE) {
                            col = cs.getBaseColor((char) readBases[readIndex]);
                        } else {
                            col = cs.getColor(samRecord.getReadNegativeStrandFlag() ? ColourKey.REVERSE_STRAND
                                    : ColourKey.FORWARD_STRAND);
                        }

                        if (baseQualityEnabled && col != null) {
                            col = new Color(col.getRed(), col.getGreen(), col.getBlue(), getConstrainedAlpha(
                                    (int) Math.round((baseQualities[readIndex] * 0.025) * 255)));
                        }

                        double xCoordinate = gp.transformXPos(sequenceCursor + i);
                        double top = gp.transformYPos(0) - ((level + 1) * unitHeight) - offset;
                        if (col != null) {
                            opRect = new Rectangle2D.Double(xCoordinate, top, unitWidth, unitHeight);
                            g2.setColor(col);
                            g2.fill(opRect);
                        }
                        if (lastMode != DrawingMode.SEQUENCE && mismatched && fontFits) {
                            // If it's a real mismatch, we want to draw the base letter (space permitting).
                            g2.setColor(new Color(10, 10, 10));
                            String s = new String(readBases, readIndex, 1);
                            charRect = fm.getStringBounds(s, g2);
                            g2.drawString(s, (float) (xCoordinate + (unitWidth - charRect.getWidth()) * 0.5),
                                    (float) (top + fm.getAscent() + (unitHeight - charRect.getHeight()) * 0.5));
                        }
                    }
                }
            }
            break;

        case N: // Skipped
            opRect = new Rectangle2D.Double(opStart, gp.transformYPos(0) - ((level + 1) * unitHeight) - offset,
                    opWidth, unitHeight);
            g2.setColor(cs.getColor(ColourKey.SKIPPED));
            g2.fill(opRect);
            break;

        default: // P - passing, H - hard clip, or S - soft clip
            break;
        }
        if (operator.consumesReadBases()) {
            readCursor += operatorLength;
        }
        if (operator.consumesReferenceBases()) {
            sequenceCursor += operatorLength;
        }
    }
    for (Rectangle2D ins : insertions) {
        drawInsertion(g2, ins.getX(), ins.getY(), ins.getWidth(), ins.getHeight());
    }
}

From source file:business.ImageManager.java

private void doDrawPath(Graphics2D big, Point ori, Point dest, Color color) {
    //setup para os rastros
    big.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    big.setStroke(new BasicStroke(0.75f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1f,
            new float[] { 3f, 5f, 7f, 5f, 11f, 5f, 15f, 5f, 21f, 5f, 27f, 5f, 33f, 5f }, 0f));
    big.setColor(color);/* ww w . ja  v  a 2  s.co  m*/
    //draw path
    Path2D.Double path = new Path2D.Double();
    path.moveTo(ori.getX(), ori.getY());
    path.lineTo(dest.getX(), dest.getY());

    //draw on graph
    big.draw(path);
}

From source file:com.github.lucapino.sheetmaker.renderer.JavaTemplateRenderer.java

private void processTextElement(Graphics2D g2, Element textElement) {

    int x = Integer.valueOf(textElement.getAttributeValue("X"));
    int y = Integer.valueOf(textElement.getAttributeValue("Y"));
    int width = Integer.valueOf(textElement.getAttributeValue("Width"));
    int height = Integer.valueOf(textElement.getAttributeValue("Height"));
    String alignment = textElement.getAttributeValue("TextAlignment");
    boolean multiline = Boolean.valueOf(textElement.getAttributeValue("Multiline").toLowerCase());
    boolean antiAlias = textElement.getAttributeValue("TextQuality").equalsIgnoreCase("antialias");

    Font font = parseFont(textElement.getAttributeValue("Font"));

    logger.info("Using font " + font);
    // now get the textim4java performance
    String text = textElement.getAttributeValue("Text");
    // if text matches pattern of %VARIABLE%{MODIFIER}
    logger.info("parsing token {}", text);
    Matcher matcher = pattern.matcher(text);
    int start = 0;
    while (matcher.find(start)) {
        // apply modification
        text = text.replace(matcher.group(), applyModifier(matcher.group()));
        start = matcher.end();/*from  ww  w  .j a va 2  s  .c  o  m*/
    }
    BufferedImage tmpImage;
    if (width > 0 && height > 0) {
        // create a transparent tmpImage
        tmpImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    } else {
        FontMetrics fm = g2.getFontMetrics(font);
        Rectangle outlineBounds = fm.getStringBounds(text, g2).getBounds();
        //         we need to create a transparent image to paint
        tmpImage = new BufferedImage(outlineBounds.width, outlineBounds.height, BufferedImage.TYPE_INT_ARGB);
    }
    Graphics2D g2d = tmpImage.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
    //        }
    g2d.setFont(font);
    Color textColor = new Color(Integer.valueOf(textElement.getAttributeValue("ForeColor")));
    g2d.setColor(textColor);
    Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .8f);
    g2d.setComposite(comp);
    drawString(g2d, text, new Rectangle(0, 0, width, height), Align.valueOf(alignment), 0, multiline);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
    tmpImage = processActions(textElement, tmpImage);

    ////        Graphics2D g2d = tmpImage.createGraphics();
    //        // set current font
    //        g2.setFont(font);
    ////        g2d.setComposite(AlphaComposite.Clear);
    ////        g2d.fillRect(0, 0, width, height);
    ////        g2d.setComposite(AlphaComposite.Src);
    //        // TODO: we have to parse it
    //        int strokeWidth = Integer.valueOf(textElement.getAttributeValue("StrokeWidth"));
    //        // the color of the outline
    //        if (strokeWidth > 0) {
    ////            Color strokeColor = new Color(Integer.valueOf(textElement.getAttributeValue("StrokeColor")));
    ////            AffineTransform affineTransform;
    ////            affineTransform = g2d.getTransform();
    ////            affineTransform.translate(width / 2 - (outlineBounds.width / 2), height / 2
    ////                    + (outlineBounds.height / 2));
    ////            g2d.transform(affineTransform);
    ////            // backup stroke width and color
    ////            Stroke originalStroke = g2d.getStroke();
    ////            Color originalColor = g2d.getColor();
    ////            g2d.setColor(strokeColor);
    ////            g2d.setStroke(new BasicStroke(strokeWidth));
    ////            g2d.draw(shape);
    ////            g2d.setClip(shape);
    ////            // restore stroke width and color
    ////            g2d.setStroke(originalStroke);
    ////            g2d.setColor(originalColor);
    //        }
    ////        // get the text color
    //        Color textColor = new Color(Integer.valueOf(textElement.getAttributeValue("ForeColor")));
    //        g2.setColor(textColor);
    ////        g2d.setBackground(Color.BLACK);
    ////        g2d.setStroke(new BasicStroke(2));
    ////        g2d.setColor(Color.WHITE);
    //        // draw the text
    //
    //        drawString(g2, text, new Rectangle(x, y, width, height), Align.valueOf(alignment), 0, multiline);
    //        g2.drawString(text, x, y);
    //        Rectangle rect = new Rectangle(x, y, width, height); // defines the desired size and position
    //        FontMetrics fm = g2.getFontMetrics();
    //        FontRenderContext frc = g2.getFontRenderContext();
    //        TextLayout tl = new TextLayout(text, g2.getFont(), frc);
    //        AffineTransform transform = new AffineTransform();
    //        transform.setToTranslation(rect.getX(), rect.getY());
    //        if (Boolean.valueOf(textElement.getAttributeValue("AutoSize").toLowerCase())) {
    //            double scaleY
    //                    = rect.getHeight() / (double) (tl.getOutline(null).getBounds().getMaxY()
    //                    - tl.getOutline(null).getBounds().getMinY());
    //            transform.scale(rect.getWidth() / (double) fm.stringWidth(text), scaleY);
    //        }
    //        Shape shape = tl.getOutline(transform);
    //        g2.setClip(shape);
    //        g2.fill(shape.getBounds());
    //        if (antiAlias) {
    // we need to restore antialias to none
    //            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
    //        }
    //        g2.drawString(text, x, y);
    // alway resize
    //        BicubicScaleFilter scaleFilter = new BicubicScaleFilter(width, height);
    //        tmpImage = scaleFilter.filter(tmpImage, null);
    // draw the image to the source
    g2.drawImage(tmpImage, x, y, width, height, null);
    try {
        ScreenImage.writeImage(tmpImage, "/tmp/images/" + textElement.getAttributeValue("Name") + ".png");
    } catch (IOException ex) {

    }

}

From source file:eu.udig.style.advanced.utils.Utilities.java

/**
 * Creates an {@link Image} for the given rule.
 * //  w  w w  .j  a  va 2s  .  c  o m
 * @param rule the rule for which to create the image.
 * @param width the image width.
 * @param height the image height.
 * @return the generated image.
 */
public static BufferedImage polygonRuleToImage(final Rule rule, int width, int height) {
    DuplicatingStyleVisitor copyStyle = new DuplicatingStyleVisitor();
    rule.accept(copyStyle);
    Rule newRule = (Rule) copyStyle.getCopy();

    Stroke stroke = null;
    Symbolizer[] symbolizers = newRule.getSymbolizers();
    if (symbolizers.length > 0) {
        Symbolizer symbolizer = symbolizers[0];
        if (symbolizer instanceof PolygonSymbolizer) {
            PolygonSymbolizer polygonSymbolizer = (PolygonSymbolizer) symbolizer;
            stroke = SLDs.stroke(polygonSymbolizer);
        }
    }
    int strokeSize = 0;
    if (stroke != null) {
        strokeSize = SLDs.width(stroke);
        if (strokeSize < 0) {
            strokeSize = 0;
            stroke.setWidth(ff.literal(strokeSize));
        }
    }

    // pointSize = width;
    BufferedImage finalImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    // Polygon polygon = d.polygon(new int[]{40,30, 60,70, 30,130, 130,130, 130,30});

    int[] xy = new int[] { (int) (height * 0.15), (int) (width * 0.20), (int) (height * 0.4),
            (int) (width * 0.3), (int) (height * 0.85), (int) (width * 0.15), (int) (height * 0.85),
            (int) (width * 0.85), (int) (height * 0.15), (int) (width * 0.85) };
    Polygon polygon = d.polygon(xy);
    d.drawDirect(finalImage, d.feature(polygon), newRule);
    Graphics2D g2d = finalImage.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.drawImage(finalImage, 0, 0, null);
    g2d.dispose();

    return finalImage;
}