I am a beginner in java, and I am trying to write a simple screen-capture program. I wrote a simple SWING desktop app with a button and a text-field, and what I am trying to do is, when a user clicks that button the app takes a snapshot of the screen using awt.Robot, and sends that image and the text to a PHP script on my server.
My snapshot function so far is:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = new File("screenshot_full.png");
ImageIO.write(bufferedImage, "png", file);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
As you can see it's fairly simple so far, however I am not sure how to send that image to my PHP script without actually storing the image on user's PC.
Oh and I am using apache httpClient library for communicating to the web server. For the text I guess I can pass it in the URL as a get query, but I am not sure what to do about the image.
ImageIO.write can to an OutputStream of your choice.
So if you don't want to write the image to a File, you can simply write it to a different stream instead...
For example...
OutputStream os = null;
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
os = ...;
ImageIO.write(bufferedImage, "png", os);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
os.close();
} catch (Exception exp) {
}
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
Of course, I have no idea where you're sending the data, so you'll need to define the OutputStream yourself.
If you have the memory for it, you could write it a ByteArrayOutputStream and then write this to whatever output stream you need in the future...
To slightly modify your existing method, perhaps you could use a temporarily file and then delete it when you are finished with it. Perhaps it might look something like:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = File.createTempFile(Long.toString(System.currentTimeMillis()), ".png");
ImageIO.write(bufferedImage, "png", file);
//send image
file.delete();
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
Another alternative would be to construct an int[][] from your BufferedImage which will hold the RGB values for every pixel of the image:
public int[][] getColors(final BufferedImage image){
assert image != null;
final int[][] colors = new int[image.getWidth()][image.getHeight()];
for(int x = 0; x < colors.length; x++)
for(int y = 0; y < colors[x].length; y++)
colors[x][x] = image.getRGB(x, y);
return colors;
}
I am a little unsure about what you hope to achieve; What do you plan on doing with the image?
Why don't you make this a WebsService and let your PHP consume it? You could send the binary data through the WebsService using some sort of Base64 encoder.
You could do this to get the bytes of the BufferedImage:
byte[] binaryData = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();
Related
I want to take a screenshot of my screen while in Google Chrome but when my screenshot saves its only my desktop? Im on a mac btw
try {
Robot robot = new Robot();
String format = "jpg";
String fileName = "FullScreenshot." + format;
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
ImageIO.write(screenFullImage, format, new File(fileName));
System.out.println("A full screenshot saved!");
} catch (AWTException | IOException ex) {
System.err.println(ex);
}
I have an image and I do somethings with it, finally I get an BufferedImage object(the sub image of original image), now I want to save the sub image to FastDFS without save it in my local, what should I do?
I have already save sub image as file to my local, but I don't want to do like this, because it makes waste.
String oriPicPathInFastDFS = "http://127.0.0.1/xx/xx/xx/xx";
BufferedImage image = null;
try {
image = ImageIO.read(new URL(oriPicPathInFastDFS));
} catch (IOException e) {
e.printStackTrace();
}
// do something
// this is the sub image that I want to save to FastDFS
BufferedImage subImage = image.getSubimage(5, 5, 5, 5);
// these code can save the sub image to my local and then upload to fastDFS
String localPath = "/home/xx/x/xx.jpg";
File detectionFile = new File(localPath);
try {
detectionFile.createNewFile();
ImageIO.write(subImage, "jpg", detectionFile);
} catch (IOException e) {
e.printStackTrace();
}
// upload to fast dfs
I want to upload the subImage to fastDFS without save it to my local.
Fine, I got a method to solve this question.
// change the BufferedImage to byte[]
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
boolean flag = ImageIO.write(sunImage, "jpg", out);
} catch (IOException e) {
e.printStackTrace();
}
byte[] byteArray = out.toByteArray();
// then save the byteArray to fast DFS
I have the code below on a tomcat server. The goal is to save in .jpg an image (that is sent in String) and create the equivalent thumbnails.
The goal is properly achieved nevertheless I noticed that at every execution (even after trying to set almost all used variables "null"), the server memomy increases by 6 Megabytes which are never freed. Since I have a very small RAM's server, this is really problematic. By the way images sent are close to 30 kilobytes only.
public boolean saveImage(String picInString)
throws IOException {
byte[] bytes = null;
try {
bytes = Base64.decode(picInString);
} catch (Base64DecodingException e) {
e.printStackTrace(System.out);
}
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("png");
ImageReader reader = (ImageReader) readers.next();
Object source = bis;
ImageInputStream iis = ImageIO.createImageInputStream(source);
Graphics2D g2 = null;
try {
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
// got an image file
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),
image.getHeight(null), BufferedImage.TYPE_INT_RGB);
// bufferedImage is the RenderedImage to be written
g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
ImageIO.write(bufferedImage, "jpg", new File("/image.jpg"));
ImageIO.write(Scalr.resize(MyImageClass.cropImage(bufferedImage), 100, 100),
"jpg", new File("/image_mini.jpg"));
bufferedImage.flush();
bufferedImage = null;
} catch (Exception e) {
e.printStackTrace(System.out);
} finally {
if (reader != null) {
reader.dispose();
}
if (g2 != null) {
g2.dispose();
}
bis.close();
iis.close();
reader = null;
bis = null;
iis = null;
}
return false;
}
Any help will be appreciated!
Someone gave me a clue to the answer but I am not able to see the comment anymore.
Actually, setting the variable "image" to null at the end of the process has solved the issue.
You shouldn't tame an image as it is. You should down sample it like it is done in android. Scaling is a must to prevent memory errors and exceptions. This SO questions is the solution to all your problems.
How to improve the performance of g.drawImage() method for resizing images
I am trying to convert pages of a pdf to .pbm images. I am using following code for conversion:
for (int i=0; i<pages.size(); i++) {
PDPage singlePage = (PDPage) pages.get(i);
int pageno=i+1;
BufferedImage buffImage = null;
String imagefilename=prefix+"-"+pageno+".pbm";
try {
buffImage = singlePage.convertToImage();
} catch (IOException e1) {
System.out.println("Font not found");
return;
}
try {
File output=new File(imagefilename);
if (buffImage!=null){
ImageIO.write( buffImage, "pbm", output);
}
} catch (Exception e) {
System.out.println("File can not be written, check permission?");
}
}
When I am trying to write to png files, this seem to work perfectly, but I can not write to pbm files. ImageIO.write( buffImage, "pbm", output); returns false. What can be a possible remedy?
Here is the code I have now:
File file= new File("C:\Documents and Settings\vasanth\Desktop\s.PNG");
BufferedImage image;
try {
image = ImageIO.read(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Raster raster = image.getRaster();
BufferedImage image2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
WritableRaster raster2 = image2.getRaster();
BufferedImage image3 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
WritableRaster raster3 = image3.getRaster();
Should I keep the image that I am using here? Even though I have specified the full path to the image file, I still get an error.
Use double slash in java strings. Single slash is considered a character escape sequence.
So you should open the file like so:
File file= new File("C:\\Documents and Settings\\vasanth\\Desktop\\s.PNG");
Along with what Ivaylo said, have a look at this portion of code:
BufferedImage image;
try {
image = ImageIO.read(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Raster raster = image.getRaster();
Have you considered what happens if you have an exception assigning image? You will call a method on a null object and that will kill your app entirely with a NullPointerException.
You need to stop whatever you wanted to do with the image if an exception occurs. You can put all of it within the try...catch block to fix this.