问题
This is the final output of my thread that takes screenshots and stores them in a vector.java.awt.Robot
is used to take screenshots which are basically rasters of the screen and does not contain cursor position. As a way around, I use the MouseInfo
class to get PointerInfo
and then get a Point
. Then draw an image at that point.
All is cool if recording area is set to full screen resolution. However if I change the recording area, the cursor gets drawn at the wrong position.
This black cursor is supposed to be at the Play button of the Eclipse IDE, at the top. However it is at the wrong position.
How do I draw it at the right position?
Code:
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.insertElementAt(takeScreenShot(), 0);
sleep(sleepTime);
keepCapturing = false; //take only one shot
System.out.println("here");
JFrame frame = new JFrame("blah");
frame.setVisible(true);
JLabel label = new JLabel(new ImageIcon(screenShots.firstElement()));
frame.setSize(recordingArea.width, recordingArea.height);
frame.add(label);
}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);
r.x = 200;
r.y = 200;
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;
}
If the cursor goes out of the recording bounds, it must not be drawn. I mean, you get the point right?
Output at full screen resolution
回答1:
Of course you must draw a cursor in a relative position - not global:
p = m.getPointerInfo();
Point location = p.getLocation();
gives you mouse position on screen (global). Mouse position in your image coordinates (relative) would be something like:
int x = (int) (p.x - recordingArea.getX()); //for int y similar
if(x < 0 || y < 0 || y >= maxHeight || x >= maxWidth) { // don't draw cursor }
回答2:
You're drawing the pointer at the same position as the run button still, because you don't ever check if the pointer's position is in your recording bounds. Also, you might want to scale your pointer's position with your recording bounds.
For example, you can check to see if the pointer is left or up from the viewing rectangle by doing something like this (Offset variables are basically how far away from the left and top did you start recording):
p = m.getPointerInfo();
Point location = p.getLocation();
image = bot.createScreenCapture(recordingArea);
//Check location here.
if( location.x < recordingArea.x + <<offset x variable>> ||
location.y < recordingArea.y + <<offset y variable>>){
//Code to change cursor position to outside of viewing rectangle here.
}
if(cursor!=null){
Graphics g = image.getGraphics();
g.drawImage(((ImageIcon)cursor).getImage(), location.x,location.y,null);
}
来源:https://stackoverflow.com/questions/14014728/the-image-gets-drawn-at-the-wrong-position