【问题标题】:How to convert Graphics2D to BufferedImage?如何将 Graphics2D 转换为 BufferedImage?
【发布时间】:2016-03-08 07:27:05
【问题描述】:

我的学习中有图形课程。我目前的任务是使用 Bresenham 算法绘制一个十六进制,并使用基于堆栈的递归算法对其进行填充。所以我需要轮廓的颜色来使用洪水填充。

下面的代码使用Graphics2D 绘制线条,我需要获取每个绘制像素的颜色。据我了解,Graphics2D 是一个不包含像素的抽象。所以我需要将十六进制转换为BufferedImage,使用.getRGB()方法并获取像素的颜色。但我无法确定它的头或尾。

如何使用Graphics2D 绘制一个十六进制的BufferedImage

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));
    }
}

【问题讨论】:

标签: java swing graphics bufferedimage graphics2d


【解决方案1】:

很简单,创建一个BufferedImage然后在上面画图

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


    Graphics2D g2d = bi.createGraphics();

在您的:

中使用此图形
drawHexagon(int x, int y, int edgeLength, int thickness, Graphics2D g2d)

执行后,您将在此 BufferedImage 上进行绘图

【讨论】:

  • 考虑使用createGraphics 而不是getGraphics,因为它返回一个Graphics2D(所以没有强制转换)并且提供getGraphics 是为了向后兼容
  • “这是一个很好的提示” edit to the answer 会更好。 ;)
【解决方案2】:

如果要在 BufferedImage 上绘制而不是在面板上绘制,请从 BufferedImage 中获取 Graphics 属性并在其上绘制:

class DrawingSpace extends JPanel{    
    private BufferedImage buf;   

    public DrawingSpace(){            
        //Initialization of variables and dimensions not shown
        buf = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    }

    public void drawOnBuffer(){
        Graphics g2d = buf.createGraphics();
        g2d .setColor(Color.BLUE);    //draw the things you want
        g2d .fillOval(0,0,200,200);   //draw the things you want
        g2d .dispose();
    }
}

【讨论】:

  • extends JPanel 没有必要这样做。在显示图像时,使用带有图标的JLabel 会更容易。
  • @AndrewThompson 我在传达这个想法,如果他使用 JPanel 进行自定义绘图,他仍然可以使用 Graphics 在其他位置(例如在 BufferedImage 上而不一定在 JPanel 上)绘图。
  • 您的示例在调用 createGraphics() 时会抛出 java.lang.NullPointerException
  • 感谢所有指出我帖子中错误的人。它已被编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 2013-09-26
  • 2017-12-15
相关资源
最近更新 更多