I am building a web application, in Java, where i want the whole screenshot of the webpage, if i give the URL of the webpage as input.
The basic idea i have is to capture the display buffer of the rendering component..I have no idea of how to do it..
plz help..
There's a little trick I used for this app:
count down demo app http://img580.imageshack.us/img580/742/capturadepantalla201004wd.png
Java application featuring blog.stackoverflow.com page ( click on image to see the demo video )
The problem is you need to have a machine devoted to this.
So, the trick is quite easy.
Create an application that takes as
argument the URL you want to fetch.
Then open it with Desktop.open( url
) that will trigger the current
webbrowser.
And finally take the screenshot with
java.awt.Robot and save it to diks.
Something like:
class WebScreenShot {
public static void main( String [] args ) {
Desktop.getDesktop().open( args[0] );
Robot robot = new Robot();
Image image = robot.createScreenCapture( getScreenResolutionSize() );
saveToDisk( image );
}
}
This solution is far from perfect, because it needs the whole OS, but if you can have a VM devoted to this app, you can craw the web and take screenshots of it quite easy.
The problem of having this app as a non-intrusive app is that up to this date, there is not a good html engine renderer for Java.
For a pure-java solution that can scale to support concurrent rendering, you could use a java HTML4/CSS2 browser, such as Cobra, that provides a Swing component for the GUI. When you instantiate this component, you can call it's paint(Graphics g) method to draw itself into an off-screen image
E.g.
Component c = ...; // the browser component
BufferedImage bi = new BufferedImage(c.getWidth(), c.getHeight(), TYPE_INT_RGB)
Graphics2d g = bi.createGraphics();
c.paint(g);
You can then use the java image API to save this as a JPG.
JPEGImageEncoder encoder = JPEGCodec.createEncoder(new FileOutputStream("screen.jpg"));
enncoder.encode(bi); // encode the buffered image
Java-based browsers typically pale in comparison with the established native browsers. However, as your goal is static images, and not an interactive browser, a java-based browser may be more than adequate in this regard.
Related
I have successfully read an SVG file into an org.w3c.dom.Document to see its structure.
Now I'd like to render it to the screen using Java's AWT's Graphics2D.
Note:
I don't want to use Swing (e.g., with org.apache.batik.swing.JSVGCanvas).
All the Googling I do tells me how to write to an SVGGraphics2D. (Nifty; I use it elsewhere!)
But I don't want to do that; I want to draw to the screen.
Is there a way to do this?
Or are there lower-level Swing-independent drawing classes that JSVGCanvas uses internally to draw to an AWT graphics context?
I'd hoped to find simple, clear calls that took as parameters, e.g., a Graphics2D and a Document.
[Edit by OP: Unless I dreamt it--complete with cut-and-paste-able code--I got the answer in a comment within minutes... ; ) Here's its essence for others with the need, and so people don't waste time answering again:]
// Create a user agent and document loader
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
// Create a bridge context and GVT builder
BridgeContext ctx = new BridgeContext(userAgent, loader);
ctx.setDynamic(true);
GVTBuilder builder = new GVTBuilder();
// Build the graphics node
GraphicsNode graphicsNode = builder.build(ctx, [Document]);
// Paint the graphics node to the Graphics2D object
graphicsNode.paint([Graphics2D]);
And without that comment the image I pasted of the result made the question meaningless/confusing; now may make sense. Thank you again to that moderator-deleted poster! (I think because he asked for college money...)
I am working on a Spring-MVC project running on a Debian server, in which currently we are using html2canvas for taking screenshots of the Users browser. Due to some changes in our front-end architecture, html2canvas is no longer suitable for us..
Any idea how I can take a screenshot in a SPring-MVC project. Kindly let me know. Thank you.
Update
Anyway I can achieve this with the robot class and by putting the code inside a JSP?
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ImageIO.write(image, "png", new File(fileName));
2nd Update
I tried out the code, but it just gave screenshot of both the monitors I am running. Preferred is the webpage which is being accessed.
I need to use processing library, more specifically WordCram, to take output multiple PDF files. I do not want to use any applets, and PApplets of Processing library.
I am looking this reference page for taking only a PDF output,
import processing.pdf.*;
PGraphics pdf = createGraphics(300, 300, PDF, "output.pdf");
pdf.beginDraw();
pdf.line(50, 50, 250, 250);
pdf.dispose();
pdf.endDraw();
And this is the code for the WordCram,
new WordCram(this)
.fromWords(getWords(fromFile))
.withFont("Sawasdee")
.drawAll();
As far as I understand from this code, the WordCram constructor takes the input, this, is the class inherited by PApplet.
How am I going to use WordCram without having any PApplet?
You can do this directly from WordCram.
Make a PDF graphics context, like you have above.
Make a WordCram for the sketch, but use the toCanvas method to render to the PDF graphics context.
Advance to the next page.
Make another WordCram.
Note that this seems to render the pages in reverse order: last page first.
I was able to render a PDF successfully with this sample sketch:
import processing.pdf.*;
import wordcram.*;
// Make a PDF graphics context
PGraphics pdf = createGraphics(300, 300, PDF, "output.pdf");
pdf.beginDraw();
pdf.background(30);
// Make a WordCram for the sketch, but use the `toCanvas` method
// to render to the PDF graphics context
new WordCram(this).
fromWebPage("http://nytimes.com").
toCanvas(pdf).
withColor(color(225)).
drawAll();
// Advance to the next page
((PGraphicsPDF)pdf).nextPage();
// Make another WordCram
pdf.background(225);
new WordCram(this).
fromWebPage("http://nytimes.com").
toCanvas(pdf).
withColor(color(30)).
drawAll();
pdf.dispose();
pdf.endDraw();
exit();
i am trying to simulate a live view using a canon Camera.
I am interacting with the cam using the CanonSDK, i get an image every a short period in order to simulate a video frame by frame. This works fine, i am using java to do the backend and send the images trough BlazeDS to flex.
The problem is not getting the image, the problem is that when i load a new image using something like:
image.source=my_new_image;
the new image is loaded but it produces a short white blink and it ruins the video...
So i would like to know if the is a way to update an image on flex avoiding the blinking problem, or if i could make a video streaming from java and pick it up with flex...
Thanks in advance!!!
The easy way is to use a technique called double buffering, using two Loaders - one for the image which is visible, and one for the image which is being loaded and is invisible. When the image has completed loading it becomes visible, and the other one becomes invisible and the process repeats.
In terms of efficiency, it would be better to at least use a socket connection to the server for transferring the image bytes, preferably in AMF format since it has little overhead. This is all fairly possible in BlazeDS with some scripting.
For better efficiency you may try using a real-time frame or video encoder on the server, however decoding the video on the client will be challenging. For best performance it will be better to use the built-in video decoder and a streaming server such as Flash Media Server.
UPDATE (example script):
This example loads images over HTTP. A more efficient approach would be to use an AMF socket (mentioned above) to transfer the image, then use Loader.loadBytes() to display it.
private var loaderA:Loader;
private var loaderB:Loader;
private var foregroundLoader:Loader;
private var backgroundLoader:Loader;
public function Main()
{
loaderA = new Loader();
loaderB = new Loader();
foregroundLoader = loaderA;
backgroundLoader = loaderB;
loadNext();
}
private function loadNext():void
{
trace("loading");
backgroundLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
backgroundLoader.load(new URLRequest("http://www.phpjunkyard.com/randim/randim.php?type=1"));
}
private function loaderCompleteHandler(event:Event):void
{
trace("loaded");
var loaderInfo:LoaderInfo = event.target as LoaderInfo;
var loader:Loader = loaderInfo.loader;
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaderCompleteHandler);
if (contains(foregroundLoader))
removeChild(foregroundLoader);
var temp:Loader = foregroundLoader;
foregroundLoader = backgroundLoader;
backgroundLoader = temp;
addChild(foregroundLoader);
loadNext();
}
I am using QT Jambi (java) to make screenshots of a browser window.
My main method starts the framework like this:
QApplication.initialize(new String[1]);
ScreenshotMain widget = new ScreenshotMain();
widget.showFullScreen();
QApplication.exec();
and when the browser is done with the loading the following method is invoked and takes the screenshot.
public void loadDone() {
// Taking screenshot
QPixmap pixmap;
pixmap = QPixmap.grabWidget(browser);
pixmap.save(writeTo, "png");
System.out.println("Made screenshot "+writeTo);
browser.loadProgress.disconnect(this);
browser.loadFinished.disconnect(this);
QApplication.closeAllWindows();
}
My question now is the following:
How can I make screenshots out of an application without having to open a browser window, have it load the content. The idea is that I have a server application and I donĀ“t want to open a window to make the screenshot.
Does anyone of you have experience to make screenshots using QT Jambi in this way.
Thanks a lot for your help
Marc
This might be what you are looking for: linky