I am using a Java applet to take a screenshot of the web browser, using Java's Robot class.
Robot objRobot = new Robot ();
BufferedImage objBufferedImage = objRobot.createScreenCapture(objRectArea);
The thing works good in Windows system, taking screenshot. But in case of Mac OS X I get a blank image.
When I check the event viewer, I see the following error:
invalid context
invalid pixel format
CoreAnimation: rendering error 506
The problem is occurring for all the browsers Safari, Firefox and Chrome. My applet is a signed applet.
What might be the reason?
My machine configuration is as follows:
OS : MAC OS X
Version : 10.6.4
I've sent the error message invalid pixel format to google and received a long list of results (close to 10.000) - it looks as if the problem is not a Java problem but a configuration issue on your Mac.
Try to change display resolutions and re-run your applet. Good chance, that the error is linked to some screen resolutions (external display?). Some suggestions on the web were to fully update you OSX.
dir Robot objRobot = null;
try
{
objRobot = new Robot();
} catch(Exception ex)
{
}
Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
BufferedImage objBufferedImage = objRobot.createScreenCapture(new Rectangle(0, 0, (int)screenDim.getWidth(), (int)screenDim.getHeight()));
int areaToExportWidth = 1024;
int areaToExportHeight = 768;
//Create the image
BufferedImage exportImage =objRobot.createScreenCapture(new Rectangle(0, 0, (int)screenDim.getWidth(), (int)screenDim.getHeight()));
//Get graphics - Get the layer we can actually draw on
Graphics2D imageGraphics = (Graphics2D) exportImage.getGraphics();
//Cleanup after ourselves
imageGraphics.dispose();
//Setup to write the BufferedImage to a file
String pathToFile = "dir";
File outputDirectory = new File(pathToFile);
File outputFile = new File(pathToFile+"\\"+counter+"MyImage.png");
//Here we make sure the directory exists.
/*
* Returns TRUE if:
* The directory is MISSING
* and/or the directory IS NOT a directory
*/
if(!outputDirectory.exists() || !outputDirectory.isDirectory()){
outputDirectory.mkdirs(); //Make the directory
} // Else do nothing
//Write the file
try { //Attempt the write
ImageIO.write(exportImage, "png", outputFile);
} catch (IOException e) { //For some reason it failed so...
e.printStackTrace(); //... why did it fail?
}
Related
I am working on a Spring-MVC webapplication in which we are trying to get a screenshot of an URL. Currently I am using PhantomJS for that task, but it's too slow(>10seconds). Also, the URL's have to be with http/https and www for detecting that it's an URL. As this is a chat application, there can be simple URL's which users add like helloworld.com. Any help would be nice. Thank you.
Code:
String[] words = message.split(" ");
for( String item : words ){
boolean val = ResourceUtils.isUrl(item);
if(val){
urlIdentifier = calcUrl(item);
break;
}else {
System.out.println("Url false is "+item);
}
}
if(urlIdentifier!=null){
replies.setPreviewIdentifier(urlIdentifier);
input.put("preview_identifier",urlIdentifier);
}
Method to calculate screenshot :
private String calcUrl(String website){
try {
String identifier = String.valueOf(new BigInteger(130, random).toString(32));
String previewLocation = msg + "chatthumbs/" + identifier ;
Process proc = Runtime.getRuntime().exec("phantomjs --ssl-protocol=any " +
"/home/deploy/phantom/rasterizepdf.js " +" "+website+" " +previewLocation);
proc.waitFor();
BufferedImage image = ImageIO.read(new File("/home/akshay/testme.png"));
if(image!=null){
if (image.getWidth() > image.getHeight()) {
image = Scalr.resize(image, Scalr.Mode.FIT_TO_HEIGHT, 250, 250);
} else {
image = Scalr.resize(image, Scalr.Mode.FIT_TO_WIDTH, 250, 250);
}
image = Scalr.crop(image, 250, 250);
ImageIO.write(image, "png", new File(previewLocation));
}
return identifier;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
Any help would be nice. Thank you.
(a) I think the process of taking a screen shot is taking time. Is this code running on the same device as the chat screen? Why not use java.awt.Robot to take the screen shot ? or just save the text why do you need a screen shot?
(b) Is the system too busy/ Use on a SSD to see if faster?
(c) But curious as to the end application, is this part of a web app? How will your code run on the client systems? Or will you java agent be installed on all user systems that monitors the web page and takes screen shots? Then why use a web page, use a java app to chat, and parse the text as typed.
Parsing the text. What if user types/ pastes a long message? Are you parsing everything once or on change? Think of ways to improve that if it seems to be a problem. Ignore if not the immediate issue now.
Also if the msg is too long the parsing can take a lot of time. maybe process after every key press or change event (if paste) keep local js copy of previous text to get diff?
I am using im4java version 1.4.0 to access ImageMagick functionality from Java. It is working well for processing images to and from files.
The Developers Guide has a section on using Buffered Images instead of writing output to a file, and there is a test (TestCase13) that demonstrate using Buffered Images as output. However, when I run any action with a Buffered Image I receive an org.im4java.core.CommandException stating: no ImageReader for given format.
I have tried a number of different things (including adding the jai_imageio.jar to provide additional formats), but nothing seems to work. A basic test-code that shows the problem, (based on im4java.jar's TestCase13) is:
#Test
public void shouldWorkWithBufferedImageTest() throws InterruptedException, IOException, IM4JavaException {
ProcessStarter.setGlobalSearchPath("C:\\Program Files\\ImageMagick-6.8.9-Q8");
String iImageDir = "C:\\images";
String var1 = "png";
IMOperation imOp = new IMOperation();
imOp.addImage(new String[]{iImageDir + "sample-image=6.png"});
imOp.blur(Double.valueOf(2.0D)).paint(Double.valueOf(10.0D));
imOp.addImage(new String[]{var1 + ":-"});
ConvertCmd convertCmd = new ConvertCmd();
Stream2BufferedImage stream2BufferedImage = new Stream2BufferedImage();
convertCmd.setOutputConsumer(stream2BufferedImage);
convertCmd.run(imOp, new Object[0]);
BufferedImage outImage = stream2BufferedImage.getImage();
ImageIO.write(outImage, "PNG", new File(iImageDir + "tmpfile.png"));
DisplayCmd.show(iImageDir + "tmpfile.png");
}
Running this throws the following error:
org.im4java.core.CommandException: java.lang.IllegalStateException: no ImageReader for given format
at org.im4java.core.ImageCommand.run(ImageCommand.java:219)
at test.groovy.services.ImageManipulation.JavaBufferedImageManipulationTest.shouldWorkBufferedImageTest(JavaBufferedImageManipulationTest.java:31)
Caused by: java.lang.IllegalStateException: no ImageReader for given format
at org.im4java.core.Stream2BufferedImage.consumeOutput(Stream2BufferedImage.java:82)
at org.im4java.process.ProcessStarter.processOutput(ProcessStarter.java:276)
at org.im4java.process.ProcessStarter.access$200(ProcessStarter.java:54)
at org.im4java.process.ProcessStarter$2.call(ProcessStarter.java:433)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.lang.Thread.run(Thread.java:745)
The error occurs on the the convertCmd.run line, however, the problem seems to be with setting the outputConsumer as the stream2BufferedImage. How do I fix this? Is there a known bug with im4java and BufferedImages? Is there a better work-around than exporting to a temp-file and then reading it back in to a BufferedImage? I am aware of JMagick (as an alternative to im4java) but have not found this a good solution for other reasons.
Thanks, in advance, for any assistance or ideas.
see in this example i have the input source as buffered Image and output is also as buffered image . I hope this can help you.
public static void main(String... args) throws Exception {
IMOperation op = new IMOperation();
op.addImage();
op.resize(350)
op.addImage("png:-")
BufferedImage images = ImageIO.read(new File("image.jpg"));
// set up command
ConvertCmd convert = new ConvertCmd();
Stream2BufferedImage s2b = new Stream2BufferedImage();
convert.setOutputConsumer(s2b);
// run command and extract BufferedImage from OutputConsumer
convert.run(op,images);
BufferedImage img = s2b.getImage();
}
I make an introduction of the scenario:
A web service (SpringMVC) through an action with parameters dynamically generate images with text and returns the response to the client.
This service processes about 500 images per minute.
The images are generated with the library SWT [1]. This works fine locally.
To test or production environments, the application is installed on a server without X (CentOS / Ubuntu). And that SWT can draw the images requires the DISPLAY environment variable set correctly. So on the server install Xvfb package to emulate an X environment virtually.
Xvfb: 1-screen 0 1x1x24-dpi 96 &
DISPLAY = localhost: 1.0
export DISPLAY
$TOMCAT/bin/startup.sh
This works fine the first few minutes, but eventually the memory occupied by the Xvfb process grows without limit (from 1 mb to 1.3 Gb and growing ...).
I tried with different configurations and parameters Xvfb [3], but have not had success.
Xvfb: 1-screen 0 1x1x24 -dpi 96 -noreset &
Xvfb: 1-screen 0 1x1x24 -dpi 96 -reset &
Xvfb: 1-screen 0 1x1x24 -dpi 96 -ld 262144 -ls 262144 -lf 1024 &
Took several days with this problem without a solution?
I could guide you more try or where freshened?
[1]
public BufferedImage drawImage () {
// example code, real code is more complex
FontData [] FontData fontData = new [] {new FontData ("Arial", 8, SWT.NORMAL)};
Display display = this.getDisplay ();
Image image = new Image (display, IMAGE_WIDTH, IMAGE_HEIGHT);
GC gc = new GC (image);
gc.setAntialias (SWT.ON);
gc.setInterpolation (SWT.HIGH);
gc.setBackground (display.getSystemColor (SWT.COLOR_WHITE));
gc.fillRectangle (0, 0, this.image.getBounds (). width, this.image.getBounds (). height);
gc.setFont (new Font (display, fontData [0]));
gc.setForeground (display.getSystemColor (SWT.COLOR_RED));
gc.drawText ("Text to draw in image", 5, 6);
BufferedImage bi = null;
bi = this.convertToAWT (hi.getImage (). getImageData ());
return bi;
}
#RequestMapping
public void RetrieveImage (HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType ("image / png");
BufferedImage image = drawImage ();
ByteArrayOutputStream os = new ByteArrayOutputStream ();
ImageIO.write (bi, "png", os);
InputStream is = new ByteArrayInputStream (os.toByteArray ());
IOUtils.copy (is, response.getOutputStream ());
}
Update:
Add getDisplay method.
private Display getDisplay() throws DrawImageException {
if (display == null || display.isDisposed()) {
LOGGER.debug("Initializing display...");
try {
display = Display.getDefault();
} catch (Exception e) {
throw new DrawImageException("Can't get default display", e);
}
}
return display;
}
Solved
As Baz and Niranjan said, the problem was with the release of SWT resources. Now work fine.
When I simply create a new image from another like this:
public static void scaleByTwoRight(String src, String dest)
throws IOException {
BufferedImage bsrc = ImageIO.read(new File(src));
int width = bsrc.getWidth()/2;
int height = bsrc.getHeight();
BufferedImage bdest = bsrc.getSubimage(width, 0, width, height);
ImageIO.write(bdest,"PNG",new File(dest));
}
Source file (src) = C:...\Manga\Shonan Juna_ Gumi Tome 11\Shonan Junaï Gumi Tome 11 - 091B.png
Destination file (dest) = C:...\Manga\Shonan Junaï Gumi Tome 11 - 091B_A.png
Example of generated file: https://docs.google.com/file/d/0B1vKCZzB5hxqYzNsUWF5RHA2Wm8/edit?usp=sharing
Problem: The new image has mimetype: application instead of mimetype: image
How I arrive to this conclusion: I'm using a function to test if the file is an image or not:
public static boolean isImage(String src)
throws IOException {
File f = new File(src);
String mimetype= new MimetypesFileTypeMap().getContentType(f);
String type = mimetype.split("/")[0];
if(type.equals("image")){
return true;
}else{
System.out.println("mimetype: "+type);
return false;
}
}
It has not a huge impact if the Mime-type is not correct but I prefer to have that working properly..
Thanks for your help!
Note:
I'm running under Windows 7 / 32b
JVM 1.7 / Eclipse Helios
Your code is working fine in my machine.
I have windows XP,32 bit,
Tried with jpeg image and it is returning the mimetype as image/jpeg only.
Hope you are not trying to execute both the functions simultaneously.
Also the destination file name should contain proper extension like .jpeg or. png etc...
i have an application that loads an image to create a button with an icon in it. When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.
Location of images :
+Project
-Source Packages
-Tools
-start.jpg
The code used :
static final String STARTIMAGE = "/Tools/start.JPG";
public static JButton createStartButton() {
Image img = Toolkit.getDefaultToolkit().getImage(GUITools.class.getResource(STARTIMAGE));
JButton b = new JButton("",new ImageIcon(img));
b.setPreferredSize(smallButton);
b.setMaximumSize(smallButton);
b.setMinimumSize(smallButton);
return b;
Now, the weirdest thing is that in another screen, a button is created in the exact same way, and this one works just fine...
Code:
static final String PREVIOUSIMAGE = "/Tools/previous.gif";
public JButton createPreviousButton(){
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
JButton b = new JButton("Previous",new ImageIcon(img));
b.setPreferredSize(dimensionButton);
b.setMaximumSize(dimensionButton);
b.setMinimumSize(dimensionButton);
return b;
}
The only difference is that one is static, but even if make it non-static like the other one, it still won't work.
I tried everything I found on this forum and other sites, including this good topic :
How to bundle images in jar file
(The generated url at the end of the topic is just 'null')
Nothing seems to work... Please help!
Thanks!
When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
This approach above is incorrect, use this instead:
private static BufferedImage readBufferedImage (String imagePath) {
try {
InputStream is = YourClassName.class.getClassLoader().getResourceAsStream(imagePath);
BufferedImage bimage = ImageIO.read(is);
is.close();
return bimage;
} catch (Exception e) {
return null;
}
}
And better load all images at application startup and then use them.
It seems to me that your images are inside a package so the actual link might be "package.name/Tools/start.jpg" or something else when its compiled so the image should be moved.
Instead of having it inside of a package like:
+Project
-Source Packages
-Tools
-start.jpg
Do something like this instead.
+Project Folder
-Source Packages/
-Tools/
-start.jpg