Search code examples
javaswinggraphicsbufferedimagegraphics2d

How to convert Graphics2D to BufferedImage?


I have graphics course on my study. My current task is to draw a hex using Bresenham algorithm and flood fill it using stack-based recursive algorithm. So I need the color of a contour to use flood filling.

The code below draws lines using Graphics2D, and I need to get color of each drew pixel. As I understand, Graphics2D is an abstraction which doesn't contain pixels. So I need to convert the hex to BufferedImage, use .getRGB() method and get the color of the pixel. But I can't make head or tail of it.

How can I make the BufferedImage of a hex drew with the Graphics2D?

public void drawHexagon(int x, int y, int edgeLength, int thickness, Graphics2D g2d) {
    int cosEdgeLength = (int) (Math.cos(Math.PI / 6) * edgeLength);
    BufferedImage image = new BufferedImage(edgeLength*2, cosEdgeLength*2 + edgeLength, BufferedImage.TYPE_INT_RGB);
    drawBresenhamLine(x, y, x - edgeLength, y + cosEdgeLength, g2d, thickness);
    drawBresenhamLine(x, y, x + edgeLength, y + cosEdgeLength, g2d, thickness);
    drawBresenhamLine(x - edgeLength, y + cosEdgeLength, x - edgeLength, y + cosEdgeLength + edgeLength, g2d, thickness);
    drawBresenhamLine(x + edgeLength, y + cosEdgeLength, x + edgeLength, y + cosEdgeLength + edgeLength, g2d, thickness);
    drawBresenhamLine(x + edgeLength, y + cosEdgeLength + edgeLength, x, y + cosEdgeLength + edgeLength + cosEdgeLength, g2d, thickness);
    drawBresenhamLine(x - edgeLength, y + cosEdgeLength + edgeLength, x, y + cosEdgeLength + edgeLength + cosEdgeLength, g2d, thickness);
    g2d.drawImage(image, null, 0, 0);
}

void drawBresenhamLine (double xstart, double ystart, double xend, double yend, Graphics2D g, int thickness)
{
    double x, y, dx, dy, incx, incy, pdx, pdy, es, el, err;
    dx = xend - xstart;
    dy = yend - ystart;
    incx = sign(dx);
    incy = sign(dy);
    if (dx < 0) dx = -dx;
    if (dy < 0) dy = -dy;
    if (dx > dy) {
        pdx = incx; pdy = 0;
        es = dy;    el = dx;
    } else {
        pdx = 0;    pdy = incy;
        es = dx;    el = dy;
    }
    x = xstart;
    y = ystart;
    err = el/2;
    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
    g.draw(new Line2D.Double(x, y, x, y));
    for (int t = 0; t < el; t++) {
        err -= es;
        if (err < 0) {
            err += el;
            x += incx;
            y += incy;
        } else {
            x += pdx;
            y += pdy;
        }
        g.draw(new Line2D.Double(x, y, x, y));
    }
}

Solution

  • It is very simple, create a BufferedImage then draw on it

        int width = 500; // example value
        int height = 500; // example value
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    
    
        Graphics2D g2d = bi.createGraphics();
    

    use this graphics in your:

    drawHexagon(int x, int y, int edgeLength, int thickness, Graphics2D g2d)
    

    after execution you will have the drawing on this BufferedImage