質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Java

    14101questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Swing

    230questions

    SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

[JAVA Swing]キャプチャツールのキャプチャ範囲指定

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,158

junn

score 59

以下のツールを使って画面キャプチャツールをつくっていっるのですが、キャプチャするとフルスクリーンでキャプチャされてしまいます。
指定の範囲やマウスで範囲指定した時などのキャプチャ方法が知りたいです。
マウスリスナーを使い範囲指定するのかなというところまでわかりました。

実際に追加するソースコード等を教えていただけると
助かります。

MainInit
public class MainInit implements ActionListener, MouseListener, MouseMotionListener{        //impriments(組み込む)
    private JFrame mainFrame;
    private Container contentPane;
    private JPanel itemPanel;
    private JPanel textPanel;
    private JPanel buttonPanel;
    private JTextField textField;
    private JButton dirButton;
    private JButton addButton;
    private ScreenShot screenShot;
    private String  folderpath;
    private JLabel  folderlabel;


    private ItemBox itemboxtest1;
    private ItemBox itemboxtest2;
    private ItemBox itemboxtest3;
    private ItemBox itemboxtest4;

    private Thumbnail DrawPanel;

    private    JFrame    mainFrame2;
    private    Point    startPoint;
    private    Point    endPoint;
    private    int        x;
    private    int        y;
    public MainInit(){
        mainFrame = new JFrame("エビデンスキャプチャ");
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        mainFrame.setSize(500, 300);                        mainFrame.setLocationRelativeTo(null);                contentPane = mainFrame.getContentPane();   

        contentPane.setLayout(null);


        dirButton   = new JButton("Dir");            dirButton.setBounds(20, 0, 80, 30);
        contentPane.add(dirButton);                        addButton   = new JButton("Capture");
        addButton.setBounds(400, 0, 90, 60);
        contentPane.add(addButton);





        JMenuBar menubar = new JMenuBar();
        JMenu menu1 = new JMenu("設定");                    JMenu menu2 = new JMenu("ヘルプ");
        JMenuItem menuitem1 = new JMenuItem("設定");

        menubar.add(menu1);
        menubar.add(menu2);
        menu1.add(menuitem1);

        mainFrame.getRootPane().setJMenuBar(menubar);        
        folderlabel = new JLabel();
        textField   = new JTextField();            
        //「追加」ボタンとアクション・リスナーの関連付け
        dirButton.addActionListener(this);
        dirButton.setActionCommand("Dir");        addButton.addActionListener(this);
        addButton.setActionCommand("Capture")



        itemPanel    = new JPanel();                                        itemPanel.setBounds(0, 0, 500, 100);
        contentPane.add(itemPanel);
                textPanel    = new JPanel();                                        textPanel.setLayout(null);
        contentPane.add(textPanel);
        textPanel.setBounds(0,80, 500, 100);
        
        buttonPanel = new JPanel();

        buttonPanel.setLayout(null);
        contentPane.add(buttonPanel);
        buttonPanel.setBounds(0,180,500,200);
    ;


        itemboxtest1 = new ItemBox();                            
        itemPanel.add(itemboxtest1);


        itemboxtest2 = new ItemBox();
        itemPanel.add(itemboxtest2);

        itemboxtest3 = new ItemBox();
        itemPanel.add(itemboxtest3);

        itemboxtest4 = new ItemBox();
        itemPanel.add(itemboxtest4);


        textPanel.add(folderlabel);
        folderlabel.setBounds(0, 30, 200, 30);

        textPanel.add(textField);
        textField.setBounds(320, 30, 150, 30);

        buttonPanel.add(dirButton);
        buttonPanel.add(addButton);




    
        folderpath = "C:\\tmp";
                folderlabel.setText(folderpath);

        textField.setText("UT_CNT_%d-%d-%d-%d");                mainFrame.setVisible(true);
        screenShot = new ScreenShot();

    }




        public void actionPerformed(ActionEvent event){
                String cmd = event.getActionCommand();

        if(cmd.equals("Capture")){
            beforeProcess();
            int x = mainFrame.getX();
            int y = mainFrame.getY();
            



            try{
                File filepath = FilePathCreate();
                
                mainFrame.setLocation(-1000,-1000);
                
                screenShot.screenCapture(filepath, endPoint, endPoint);

            
                mainFrame.setLocation(x, y);

                new Thumbnail(filepath);            

            } catch (AWTException e){
                
                e.printStackTrace();
            } catch (IOException e){
                                e.printStackTrace();
            }


        }


        else if(cmd.equals("Dir")) {


    


        JFileChooser filechooser = new JFileChooser(folderpath);    
                 filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

                 int selected = filechooser.showSaveDialog(this.contentPane);
                 if (selected == JFileChooser.APPROVE_OPTION){
                     File file = filechooser.getSelectedFile();
                     folderpath = file.getAbsolutePath();
                     folderlabel.setText(folderpath);


                 }
             }


    }


    public File FilePathCreate() {
        String filename = FileNameCreate();
        String name = filename;
        int m = 1;
        do {
            File f = new File(folderpath, name + ".jpg");
            if (!f.exists()) {
                return f;
            }
            ++m;
            name = filename + "(" + m + ")" ;
        } while (m < 100); // 無限ループ防止
        throw new IllegalStateException("パス生成失敗");
        
    }


    public String FileNameCreate() {
        String filename;
        String[] itemNumbers = new String[4];
        filename = textField.getText();
        int i=0;
        int found = 0;

        itemNumbers[0] = itemboxtest1.getText();
        itemNumbers[1] = itemboxtest2.getText();
        itemNumbers[2] = itemboxtest3.getText();
        itemNumbers[3] = itemboxtest4.getText();

        for(i=0; i<4; i++){
            found = filename.indexOf("%d",found);
            if( found != 0 ){
                filename = filename.replaceFirst("%d",itemNumbers[i]);
            }
        }
        return filename;
    }


    public void windowDeactivated(WindowEvent we) {                    System.out.println("windowClosing");

    }
    public static void main(String[] args) {
        new MainInit();
    }

    @Override
    public void mouseClicked(MouseEvent e) {        
    }




    @Override
    public void mousePressed(MouseEvent e) {        
        startPoint = e.getPoint();

    }




    @Override
    public void mouseReleased(MouseEvent e) {        /
         endPoint = e.getPoint();
             afterProcess();

    }




    @Override
    public void mouseEntered(MouseEvent e) {        

    }




    @Override
    public void mouseExited(MouseEvent e) {
    

    }
    public void beforeProcess() {

        x = mainFrame.getX();
        y = mainFrame.getY();
        mainFrame.setLocation(-1000,-1000);


       JFrame.setDefaultLookAndFeelDecorated(false);
       mainFrame2 = new JFrame();
       mainFrame2.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
       Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
       mainFrame2.setSize(screenSize.width, screenSize.height);
       JPanel p = new JPanel();
       p.setBackground(new Color(.5f,.5f,.5f,.5f));
       mainFrame2.getContentPane().add(p);

       mainFrame2.setLocationRelativeTo(null);
       mainFrame2.setUndecorated(true);

       com.sun.awt.AWTUtilities.setWindowOpaque(mainFrame2, false);        //半透明化
       mainFrame2.addMouseListener(this);
       mainFrame2.addMouseMotionListener(this);
       mainFrame2.setVisible(true);
       
   }

   public void afterProcess() {
       mainFrame2.dispose();
       File filepath = FilePathCreate();
       try {
           screenShot.screenCapture(filepath,startPoint,endPoint);
       } catch (AWTException e1) {
           // TODO 自動生成された catch ブロック
           e1.printStackTrace();
       } catch (IOException e1) {
           // TODO 自動生成された catch ブロック
           e1.printStackTrace();
       }
       // 自分を表示(元の位置に移動)
       mainFrame.setLocation(x, y);
   }




@Override
public void mouseDragged(MouseEvent e) {
    
}




@Override
public void mouseMoved(MouseEvent e) {
    
}

}


ScreenShot
public class ScreenShot {

    public void screenCapture(File filepath, Point startPoint, Point endPoint) throws AWTException, IOException {
        Robot robot = new Robot();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = robot.createScreenCapture(
                 new Rectangle(    (int)startPoint.getX(),
                         (int)startPoint.getY(),
                         (int )(endPoint.getX() - startPoint.getX()),
                         (int)(endPoint.getY() - startPoint.getY())));
        ImageIO.write(image, "PNG", filepath);        //PNGファイルの保存
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+1

マウスで範囲指定のキャプチャ方法です

やっている事は「Capture」ボタンを押した後に半透明なフレームを画面全体に配置し
その上でマウスのドラッグ開始・終了位置の座標とを取得し
screenCaptureに渡しているだけです

指標になれば程度なので
ドラッグ終了座標の方が大きくなったりすると恐らくエラーが出ますし、
ドラッグ範囲も表示されないので、MouseMotionListenerも追加して
ドラッグ範囲を枠で表示したりした方が機能的だったりします



MainInit 
public class MainInit implements ActionListener , WindowListener { 

    …中略…
  
    // 利用者の操作に応じた処理を実装
    public void actionPerformed(ActionEvent event){
        // コマンド文字列を取得
        String cmd = event.getActionCommand();

        if(cmd.equals("Capture")){
            …中略…
        }

public class MainInit implements ActionListener , WindowListener,MouseListener{

    …中略…

// メンバー追加
    private    JFrame    mainFrame2;
    private    Point    startPoint;
    private    Point    endPoint;
    private    int        x;
    private    int        y;

    // 利用者の操作に応じた処理を実装
    public void actionPerformed(ActionEvent event){
        // コマンド文字列を取得
        String cmd = event.getActionCommand();

        if(cmd.equals("Capture")){
        beforeProcess();
        }…中略…
  }

    // MouseListenerによる追加メソッド
    @Override
    public void mousePressed(MouseEvent e) {
        startPoint = e.getPoint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        endPoint = e.getPoint();
        afterProcess();
    }
    // 追加メソッド
    public void beforeProcess() {

         x = mainFrame.getX();
         y = mainFrame.getY();
         mainFrame.setLocation(-1000,-1000);


        JFrame.setDefaultLookAndFeelDecorated(false);
        mainFrame2 = new JFrame();
        mainFrame2.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        mainFrame2.setSize(screenSize.width, screenSize.height);
        JPanel p = new JPanel();
        p.setBackground(new Color(.5f,.5f,.5f,.5f));
        mainFrame2.getContentPane().add(p);

        mainFrame2.setLocationRelativeTo(null);
        mainFrame2.setUndecorated(true);

        com.sun.awt.AWTUtilities.setWindowOpaque(mainFrame2, false);
        mainFrame2.addMouseListener(this);
        mainFrame2.addMouseMotionListener(this);
        mainFrame2.setVisible(true);
        
    }

    public void afterProcess() {
        mainFrame2.dispose();
        File filepath = FilePathCreate();
        try {
            screenShot.screenCapture(filepath,startPoint,endPoint);
        } catch (AWTException e1) {
            // TODO 自動生成された catch ブロック
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO 自動生成された catch ブロック
            e1.printStackTrace();
        }
        // 自分を表示(元の位置に移動)
        mainFrame.setLocation(x, y);
    }

ScreenShot 
    public void screenCapture(File filepath) throws AWTException, IOException {
        Robot robot = new Robot();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = robot.createScreenCapture(
            new Rectangle(0, 0, screenSize.width, screenSize.height));
        ImageIO.write(image, "PNG", filepath);        //PNGファイルの保存
    }

    public void screenCapture(File filepath, Point startPoint, Point endPoint) throws AWTException, IOException {
        Robot robot = new Robot();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = robot.createScreenCapture(
            new Rectangle(    (int)startPoint.getX(),
                                (int)startPoint.getY(),
                                (int )(endPoint.getX() - startPoint.getX()),
                                (int)(endPoint.getY() - startPoint.getY())));
        ImageIO.write(image, "PNG", filepath);        //PNGファイルの保存
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/16 09:11 編集

    shahaさん
    解答ありがとうございます。返事が遅くなってしまいもうしわけありません。
    MainInitの追加メソッドは
    public void mouseExited(MouseEvent e) {
    // TODO 自動生成されたメソッド・スタブ

    }
    の後に追加すればよいでしょうか?

    キャンセル

  • 2015/07/16 15:24

    はい、mouseExitedの後で問題ありません

    キャンセル

  • 2015/07/16 16:34

    解答ありがとうございます。
    実行しましたところ、com.sun.awt.AWTUtilities.setWindowOpaque(mainFrame2, false);
    で「使用可能な候補はありません」とでてしまいました。。。

    キャンセル

  • 2015/07/16 18:05

    junnさんの環境がEclipseか、どうかは判りませんが
    私が設定した手順は

    「ビルドパス」→「ビルドパスの構成」→「ライブラリー」→「アクセスルール」を選択
    「編集」→「追加」で
    レゾリューションを「アクセス可能」
    ルールパターンを「com/sun/awt/*」
    で「OK」をクリック

    以上です
    これで行けると思います

    キャンセル

  • 2015/07/17 09:19 編集

    お疲れ様です。
    ルールパターンに「com/sun/awt/*」で追加したところ
    エラーが消えました!
    ただ mainFrame2.addMouseMotionListener(this);で
    「型 Component のメソッド addMouseMotionListener(MouseMotionListener) は引数 (MainInit) に適用できません」

    のエラーが出て消えません...
    引数を変えてあげなければだめなんですかね?

    キャンセル

  • 2015/07/17 10:48

    screenCaptureメソッドは、私の最初の投稿に有る様に
    引数を増やす必要があります
    (ドラッグの開始位置と終了位置を渡してあります)

    キャンセル

  • 2015/07/17 11:07

    渡してみました。’MaininitをMouseListener’に実装させるにして
    public class MainInit implements ActionListener , WindowListener,MouseListener{
    部分を
    public class MainInit implements ActionListener, WindowListener, MouseListener, MouseMotionListener
    にしました。グレーの半透明のものはできたのですが、マウスで変化させることが
    できませんでした。。。

    キャンセル

  • 2015/07/17 11:09

    screenShot.screenCapture(filepath);をscreenShot.screenCapture(filepath, startPoint, endPoint);にしてあげればよいでしょうか?

    キャンセル

  • 2015/07/17 11:59

    最初の投稿どおり、引数は
    screenShot.screenCapture(filepath);をscreenShot.screenCapture(filepath, startPoint, endPoint);
    であってます

    さらに、screenShot.screenCaptureメソッドの
    BufferedImage image = robot.createScreenCapture(
    new Rectangle(0, 0, screenSize.width, screenSize.height));
    部分を
    BufferedImage image = robot.createScreenCapture(
    new Rectangle( (int)startPoint.getX(),
    (int)startPoint.getY(),
    (int )(endPoint.getX() - startPoint.getX()),
    (int)(endPoint.getY() - startPoint.getY())));
    に、するとキャプチャされる範囲が変わります

    キャンセル

  • 2015/07/17 13:14

    お返事ありがとうございます。
    そのとおりにしたのですが、全画面にグレーのフレームができて、変更不可でした。
    エラー時に
    public void actionPerformed(ActionEvent event){
    // コマンド文字列を取得
    String cmd = event.getActionCommand();

    if(cmd.equals("Capture")){
    int x = mainFrame.getX();
    int y = mainFrame.getY();
    // 画面キャプチャー
    try{
    File filepath = FilePathCreate();
    // 自分を消す(見えない位置に移動)
    mainFrame.setLocation(-1000,-1000);
    // 画面キャプチャ
    screenShot.screenCapture(filepath);

    内のscreenShot.screenCapture(filepath);を変えたのがいけなかったでしょうか?

    キャンセル

  • 2015/07/17 13:39

    直近のコメントを見る限り、
    私のソース通りでは無い様なので、
    それだと答えようが無いのですが・・・

    グレーのフレームを出したのは、
    マウスで範囲選択をする為で、
    マウスの範囲をする表示の変化は導入してません
    (あくまで指定した範囲をキャプチャするという機能のみを記述したので)

    int x = mainFrame.getX();
    int y = mainFrame.getY();
    と、ありますが
    このx,yをクラス変数にしたのは
    マウス範囲指定が入る為、直後に処理できないので
    ローカルではなくクラス変数にしています

    キャンセル

  • 2015/07/21 09:38

    返事が遅くなりすみません。
    mainFrame2.addMouseMotionListener(this);で
    「型 Component のメソッド addMouseMotionListener(MouseMotionListener) は引数 (MainInit) に適用できません」
    エラー時に’MaininitをMouseListener’を実装したのが間違いだったのでしょうか?

    screenShot.screenCapture(filepath);をscreenShot.screenCapture(filepath, startPoint, endPoint);にして
    screenShot.screenCaptureメソッドを変えてもきえませんでした。
    理解が及ばなくて申し訳ございません。
    宜しくお願い致します。

    キャンセル

  • 2015/07/21 10:17

    addMouseMotionListener部分の為に、
    MouseMotionListenerを実装するのは問題無いです
    が、単純に後々の実装を考えてだったので私の消し忘れなので
    mainFrame2.addMouseMotionListener(this);
    自体は無くても動きます

    現在動作的には、どの様になっている状況でしょうか?

    キャンセル

  • 2015/07/21 10:34 編集

    そうなのですね。
    現在はキャプチャボタンを押すとフルスクリーンでグレーのフレームが出て、エラーに
    なっています。もう一度グレーのフレームを押下すると元に戻ります。

    キャンセル

  • 2015/07/21 11:37

    一度直したソースコードを載せたほうが良いでしょうか?

    キャンセル

  • 2015/07/21 11:43

    動いているソースを回答で投稿しようをしたのですが
    (コメントだとソースが、分かりにくい為)
    1人1回しか回答できないみたいですね…

    一応、こちらの動きとしては
    起動後
    「Capture」をクリックするとグレーになって
    その状態でマウスで範囲指定(今のところ左上から右下の順で指定いないとエラーになる)
    でキャプチャが保存される
    という感じになってます
    (ちなみに立ち上げ直後は存在しないディレクトリが指定されているので
    そのままキャプチャすると、こちらもエラーになってます)

    こんな感じです

    ソースを見た方が早いかも知れないですね

    キャンセル

  • 2015/07/22 16:36

    そうなのですね。わかりました。編集してソースコードを掲載してみます。

    キャンセル

  • 2015/07/22 17:10

    編集したソースコード載せました。文字数制限のためItemBoxを省略しました。
    必要であればまた言ってください。宜しくお願いします

    キャンセル

  • 2015/07/22 17:41

    変更されたソースで動かしてみました

    エラーログは出力されますが
    一応マウスで指定した範囲のキャプチャは
    保存されてますね

    エラーログが出力されるのは
    「Capture」ボタンが押された時に
    screenCaptureを呼んでいるからです
    マウスで範囲指定が終わってから呼んでいるので必要ないです

    キャンセル

関連した質問

同じタグがついた質問を見る

  • Java

    14101questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Swing

    230questions

    SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。