[英]Draw accurately on an image in Java
在下面的代码中,我将2dim数组转换为缓冲图像(有效,图像为二进制(背面和白色))。 然后我显示这个图像。
我现在的问题是如何更新这个图像 (因为我想在循环的每次运行中绘制一些东西,这里没有显示)。
这也引出了我的第二个问题: 我怎样才能在这张图片上画出一点 。 (这也意味着如果我想在150,100上画一个点;它应该在图像的150,100像素上)。
public void showImage(int xPoint, int yPoint) throws IOException {
// Two dim array conversion to a bufferedImage
BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < width; y++) {
for (int x = 0; x < height; x++) {
tempValue = (pixelArray[y][x]==1) ? 255 : 0;
int value = tempValue << 16 | tempValue << 8 | tempValue;
bimg.setRGB(x, y, value);
}
}
JFrame canvas = new JFrame();
canvas.setSize(bimg.getWidth(), bimg.getHeight());
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.setTitle("Contour");
Container pane = canvas.getContentPane();
ColorPanel panel = new ColorPanel(bimg,xPoint,yPoint);
pane.add(panel);
canvas.setVisible(true);
}
和
class ColorPanel extends JPanel {
BufferedImage bimg;
int x;
int y;
public ColorPanel(BufferedImage image,int _x, int _y) {
bimg = image;
x = _x;
y = _y;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bimg, null, 0, 0);
}
}
我试过的是:
g2d.setColor(Color.RED);
g2d.drawLine(x, y, x, y);
虽然每次运行都会打开一个新窗口,但我认为这一点并不在右边
我为你做了一个小例子。
基本上它是一个JFrame
带有一个名为ColorPanel
的自定义 JPanel
(与你的一些额外的方法很相似,即drawDot(..)
和setBufferedImage(..)
)
JFrame
将初始化并添加带有BufferedImage
的JPanel
(在本例中为全黑)。 此后,使用BufferedImage#setRGB(...)
每2秒在Image
以随机坐标(在图像边界内)绘制白点/像素。
我将计时器设置得更快(200milis),这就是图片看起来像:
NB它的准确性,使它成为一个明显的坐标,如drawPoint(0,0)
,你会看到(我没有证明这是一个截图不可能或任何使用)
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class PixelDotOnImage {
public PixelDotOnImage() throws Exception {
JFrame frame = new JFrame();
frame.setTitle("Random Pixel Dots On Image with Timer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
initComponents(frame);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//create frame and components on EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new PixelDotOnImage();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
private void initComponents(JFrame frame) throws Exception {
final BufferedImage bi = ImageIO.read(new URL("http://2.bp.blogspot.com/_KI3IRH6RxSs/S-uuLsgGJ3I/AAAAAAAAA5E/AA5mWBMLIvo/s1600/mat-black-lg.jpg"));
final ColorPanel cPanel = new ColorPanel(bi);
frame.add(cPanel);
//create timer to color random pixels
Timer timer = new Timer(2000, new AbstractAction() {
int xMax = bi.getWidth(), yMax = bi.getHeight();
Random rand = new Random();
@Override
public void actionPerformed(ActionEvent ae) {
int x = rand.nextInt(xMax);
int y = rand.nextInt(yMax);
if (cPanel.drawDot(x, y)) {
System.out.println("Drew white dot at: (" + x + "," + y + ")");
} else {
System.out.println("Cant draw white dot at: (" + x + "," + y + ")");
}
}
});
timer.start();
}
}
class ColorPanel extends JPanel {
private BufferedImage bimg;
private Dimension dims;
public ColorPanel(BufferedImage image) {
bimg = image;
dims = new Dimension(bimg.getWidth(), bimg.getHeight());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bimg, 0, 0, null);
}
//this method will allow the changing of image
public void setBufferedImage(BufferedImage newImg) {
bimg = newImg;
}
//ths method will colour a pixel white
public boolean drawDot(int x, int y) {
if (x > dims.getWidth() || y > dims.getHeight()) {
return false;
}
bimg.setRGB(x, y, 0xFFFFFFFF);//white
repaint();
return true;
}
@Override
public Dimension getPreferredSize() {
return dims;
}
}
希望这可以帮助。
而不是构建图像然后将其添加到JPanel,您可以考虑通过覆盖它的paintComponent方法在面板上查看绘图,如下所示:
public class PainterPanel extends JPanel {
public void paintComponent(Graphics g){
super.paintComponent(g);
// draw a diagonal line from top left to bottom right
Dimension d = getSize();
g2.draw(new Line2D.Double(0,0,d.width,d.height));
}
}
每次调用repaint()
方法时都会调用此方法(例如,通过调整框架大小或通过自己手动调用它)。 您可以进行任何需要的复杂处理,包括绘制点矩阵。
唯一的问题(如果你坚持原来的行为也是如此)是重新绘制发生在一个单独的线程中,所以你需要注意何时以及如何更新数据,以便以线程安全的方式完成。
我该如何更新此图片
paintComponent
一样使用它)。 见Javadocs 我怎样才能在这张图片上画一个点
g.drawLine(150,100,150,100)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.