2

以下のコードでは、2dim配列をバッファリングされた画像に変換します(これは機能し、画像はバイナリ(バックとホワイト)です)。次に、この画像を表示します。

私の質問は、この画像をどのように更新できるかです(ここに表示されていないループの実行ごとに何かを描画したいため)。

これはまた私の2番目の質問に私をもたらします:どうすればこの画像に点を描くことができますか。(これは、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);

実行するたびに新しいウィンドウが開き、ポイントが正しいとは思わないが

4

3 に答える 3

4

私はあなたのために小さな例を作りました。

基本的には、JFrameと呼ばれるカスタム があります(これは、いくつかの追加のメソッド、つまりandを持つあなたのものによく似ています)JPanelColorPaneldrawDot(..)setBufferedImage(..)

JFrameを初期化し、 を追加JPanelしますBufferedImage(この場合は完全に黒)。その後 . _ Image_BufferedImage#setRGB(...)

タイマーをより速く (200 ミリ秒) に設定すると、写真は次のようになります。

注意してください、正確な色を付けて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;
    }
}

お役に立てれば。

于 2012-10-16T18:22:20.043 に答える
2

この画像を更新するにはどうすればよいですか

  • 画像に描画するには、bimg.getGraphics()で取得したグラフィックを使用します(次に、の場合と同じように使用しますpaintComponent)。Javadocを参照してください

この画像に点を描くにはどうすればよいですか

  • バッファリングされた画像の特定のポイントにペイントするには、上記の回答から取得したグラフィックスオブジェクトの任意のメソッドを使用します。例g.drawLine(150,100,150,100)
于 2012-10-16T18:14:50.203 に答える
2

イメージを作成してから 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()れます (たとえば、フレームのサイズを変更するか、自分で手動で呼び出すことにより)。点の行列のプロットなど、必要なあらゆる種類の複雑な処理を実行できます。

唯一の落とし穴 (元の動作に固執している場合も同様です) は、再描画が別のスレッドで行われるため、スレッドセーフな方法でデータを更新するタイミングと方法に注意する必要があります。 .

于 2012-10-16T16:29:52.553 に答える