0
package demo;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;

public class ScreenCapturingThread extends Thread{
    public ScreenCapturingThread(Vector<BufferedImage> screenShots,
            int frameRate,
            Icon cursor,
            Rectangle recordingArea){
        this.screenShots = screenShots;
        this.frameRate = frameRate;
        this.cursor = cursor;
        this.recordingArea = recordingArea;

        try{
            bot = new Robot();
        }catch(Exception e){
            System.out.println(e);
        }
        calculateSleepTime();
    }
    @Override
    public void run(){
        while(keepCapturing == true){
            try{
                screenShots.add(takeScreenShot());
                sleep(sleepTime);

                keepCapturing = false; //take only one shot

                System.out.println("here");
                JFrame frame = new JFrame();
                frame.setSize(recordingArea.width,recordingArea.height);
                frame.getGraphics().drawImage(screenShots.firstElement(), 0, 0,frame);
                frame.repaint();
                frame.setVisible(true);

            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }
    public BufferedImage takeScreenShot(){
        p = m.getPointerInfo();
        Point location = p.getLocation();
        image = bot.createScreenCapture(recordingArea);
        if(cursor!=null){
            Graphics g = image.getGraphics();
            g.drawImage(((ImageIcon)cursor).getImage(), location.x,location.y,null);
        }

        return image;
    }
    public void stopIt(){
        keepCapturing = false;
    }
    public void calculateSleepTime(){
        sleepTime = 1/frameRate;
    }

    public static void main(String[] args) {
        Vector<BufferedImage> bufferedImages = new Vector<>(100);
        int frameRate = 10;
        Icon cursor = (Icon) new ImageIcon("src/images/blackCursor.png");
        Rectangle r = new Rectangle(1280,800);
        ScreenCapturingThread sc = new ScreenCapturingThread(bufferedImages,frameRate,cursor,r);

        sc.start();
    }
    Vector<BufferedImage> screenShots;
    int frameRate;
    long sleepTime;
    boolean keepCapturing = true;
    Icon cursor;
    Rectangle recordingArea;
    Robot bot;
    MouseInfo m;
    PointerInfo p;
    BufferedImage image;
}

説明

スクリーンレコーダーに合わせてスレッドを設計しましたが、最初にテストすることにしました. これは、それがすべきことです:

  • 適切なパラメータを渡して新しいスレッド オブジェクトを作成する
  • スクリーンショットを1 つだけ(このテスト中のみ)撮り、ベクターに保存し、run()終了する前に JFrame に描画して、キャプチャされたものを確認できるようにします。
  • 問題

    私はで取得し続けNullPointerExceptionます

    frame.getGraphics().drawImage(screenShots.firstElement(), 0, 0,frame);
    

    何が問題なのかわかりません。
    バグを見つけていただけますか?

    アップデート:

    ここに画像の説明を入力 はなくなりましNullPointerExceptionたが、本来あるべきではないフレームが空白になっています

    なんで?

    4

    1 に答える 1

    3

    JFrameGraphics表示されるまでは何も提供しません。

    JFrameが表示される前に描画したい場合は、次のようにしてはいけません。

    frame.pack();
    frame.setSize(recordingArea.width, recordingArea.height);
    Graphics g = frame.getContentPane().getGraphics();
    g.drawImage(screenShots.firstElement(), 0, 0, frame);
    

    アンドリュー・トンプソンが正しく書いたように:

    Component.getGraphics() を使用しないでください。代わりに、paint() (AWT) または paintComponent() (Swing) メソッドをサブクラス化してオーバーライドします。

    Component.getGraphics() は単に機能しません。Java は、グラフィックスの描画にコールバック メカニズムを使用します。getGraphics() を使用してグラフィック情報をコンポーネントに「プッシュ」することは想定されていません。代わりに、Java が paint()/paintComponent() メソッドを呼び出すまで待つ必要があります。その時点で、実行したい描画をコンポーネントに提供することになっています。

    代わりに、以下のようなことをしたほうがよいでしょう:

    BufferedImage img = new BufferedImage(recordingArea.width, recordingArea.height,
                        BufferedImage.TYPE_3BYTE_BGR);
                Graphics g = img.createGraphics();
                g.drawImage(screenShots.firstElement(), 0, 0, frame);
                JLabel l = new JLabel(new ImageIcon(img));
                frame.getContentPane().add(l);
    
    于 2012-12-23T20:54:59.473 に答える