2016-03-08 4 views
1

У меня есть графический курс по моему кабинету. Моя текущая задача состоит в том, чтобы нарисовать гекс, используя алгоритм Брешенема, и заливку заполнить его с помощью рекурсивного алгоритма на основе стека. Поэтому мне нужен цвет контура для заполнения наводнений.Как преобразовать Graphics2D в BufferedImage?

Код ниже рисует линии, используя Graphics2D, и мне нужно получить цвет каждого рисованного пикселя. Как я понимаю, Graphics2D - это абстракция, которая не содержит пикселей. Поэтому мне нужно преобразовать шестнадцатеричный код в BufferedImage, использовать метод .getRGB() и получить цвет пикселя. Но я не могу сделать голову или хвост.

Как я могу сделать BufferedImage из шестнадцатеричного рисунка с 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)); 
    } 
} 
+0

Посмотрите [Рисование изображения] (https://docs.oracle.com/javase/tutorial/2d/images/drawimage.html) – MadProgrammer

ответ

2

Это очень просто, создать 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

+2

Рассмотрите возможность использования 'createGraphics' над' getGraphics', так как он возвращает «Graphics2D» (так что никакого кастинга) и 'getGraphics' предоставляется для обратной совместимости – MadProgrammer

+0

@MadProgrammer, который является хорошим советом, спасибо :) –

+2

*« это хороший намек «* [Редактировать ответ] (http://stackoverflow.com/posts/35861776/edit) было бы лучше. ;) –

0

Если вы хотите нарисовать BufferedImage вместо рисования на панели, получите свойство Graphics у из BufferedImage и рисовать на ней:

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(); 
    } 
} 
+1

'extends JPanel', в этом нет необходимости. Когда дело доходит до показа изображения, проще использовать JLabel с иконкой. –

+0

@AndrewThompson Я передавал идею, если он использует JPanel для пользовательского рисования, он все равно может использовать Graphics для рисования else (например, на BufferedImage и не обязательно на JPanel). – user3437460

+0

В этом примере вызывается 'java.lang.NullPointerException' при вызове' createGraphics() '. – trashgod