Java Code to save Web page as image - java

I have an application developed using struts2. One of my web page has a div in which it displays a world map created using Google map API. On click of a button I want to save this map as an image on the server location. I tried this using the ROBOT class but this is not working. My application supports IE8. Below is the code I wrote:
Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle rect = new Rectangle(screenDim);
Robot rob = new Robot();
BufferedImage img = rob.createScreenCapture(rect);
String FileName="D:\\SP_Maps\\Map.png";
ImageIO.write(img, "png", new File(FileName));
Basically I tried to take a screen shot of the page on click of a button and save it as an image. This works fine on my local host but, when I deploy this on my server and try to get the screen shot I just get a black page saved as png image.

While you are developing a web application you may use javascript if you are interested..
To get a screen shot and save it with any format you may use PhantomJS
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast
and native support for various web standards: DOM handling, CSS selector,
JSON, Canvas, and SVG.
Check those examples written with PhantomJS:
https://github.com/ariya/phantomjs/wiki/Examples
Also check this tutorial Taking website screenshots using PhantomJS
The tutorial is about taking a web shot and saving it as JPEG, PNG, PDF ... etc
Hope this helps you...

Can you explain your use case clearly ? If I understand correctly you have a web application which has a functionality to take a screen capture upon user action? Ideally, Java Robot utility should use to do automated testing of java applications. As per the doc
The primary purpose of Robot is to facilitate automated testing of
Java platform implementations.
Maybe you can try using phantomjs.
example
var page = require('webpage').create();
page.open('http://google.com', function () {
page.render('google.png');
phantom.exit();
});
https://github.com/ariya/phantomjs/wiki/Quick-Start
To perform user actions like button clicks, you can use casper.js
http://casperjs.org/quickstart.html

Related

Customize the browser icon when running a Selenium session?

I have some Selenium sessions where, if certain events occurs, I spawn a new browser and leave the old one as is so I later on can manually intervene. The problem is that it is hard to distinguish between such a deserted browser session and the one that is currently running.
Ideally I would like to add a badge to the browser icon that is displayed in the application switcher (cmd-tab) and the dock (but other solutions/suggestions are also welcome, like add something to the name of the browser). Is that possible?
Using Java on a Mac. A solution can be platform specific.
You can use below execute_script (This python code use java equalent)
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get(
"https://stackoverflow.com/questions/9943771/adding-a-favicon-to-a-static-html-page")
head = driver.find_element_by_tag_name("head")
link = driver.find_element_by_css_selector('link[rel="shortcut icon"]')
driver.execute_script('''var link = document.createElement("link");
link.setAttribute("rel", "icon");
link.setAttribute("type", "image/png");
link.setAttribute("href", "https://i.stack.imgur.com/uOtHF.png?s=64&g=1");
arguments[1].remove();
arguments[0].appendChild(link);
''',head,link)
time.sleep(70000)
you can use link element on head tag to add favicon. THe above code is an exaple where stackoverflow site will showup with my avatar
Output:
You should find the current link the website uses, remove it and replace it with your new link as shown in the code

Is it OK to include Java Swing with JSP?

I tried using Swing code in a JSP page. To my surprise it does work well and fine.
But I cannot judge if it is OK to use Swing with JSP?
Basically I want to display some pop up reports from Database. I was thinking to display a JFrame pop up/ applet to do the trick.
But do a web browser require any additional plugin for this?
Or is it fine to do such a thingy? Any guidance will be helpful.
Always remember that every java fragment you insert into your JSP is executed server-side, so it can be deceitful (it may seem to work in your development local machine, but it is only because the server and the client side are running on the same box).
The proper way to do this would be to write an Applet and include it into your page - this way, the browser will download it to client side and run it there. You should subclass JApplet (http://docs.oracle.com/javase/8/docs/api/javax/swing/JApplet.html) and then you will be able to use Swing components at will
The library works but your controls will never be shown at the client side (browser) but at the server (if it is that you have a working window service: Ms Windows, X11, Xorg,...).
I don't think that is a good practice and I would only use Swing library classes not to show GUI components but to use some classes to store special objects such as ImageIcon to store icons. But never to try to paint them.
I have a project where I use JLaTeXMath to generate a PNG within a JSP representing some math equations, in this context, I use javax.swing.JLabel to generate the image:
TeXFormula formula = new TeXFormula(texCode);
TeXIcon texImg = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 25);
BufferedImage img = new BufferedImage(texImg.getIconWidth(), texImg.getIconHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
texImg.paintIcon(new JLabel(),img.getGraphics(), 0, 0);
try {
OutputStream os = res.getOutputStream();
res.setContentType("image/png");
ImageIO.write(img, "png", os);
os.close();
res.flushBuffer();
} catch (Exception ex) {
log.warn("LaTeX renderer: " + ex.toString() + "\t" + "Msg: " + ex.getMessage());
return;
}
the JSP would run on the server,and probably display the GUI there,
but why would you want that? In the meantime, the person at the client
who submitted the request would be sitting there waiting for somebody
at the server end to close the Swing window so the JSP could get on
with its work.
So i would say that it is not feasible.

Programatically getting a screenshot of a Java applet

I have tried to devise a way to get a screenshot of a Java applet running in a browser, but I can't seem to get it working. I managed successfully to use cutycapt to get screenshots fine from "normal" websites, but I soon found out that qtwebkit which it seems to rely on for the rendering does not support java. I also tried IEcapt thinking that it would somehow inherit the Java rendering capabilities of IE on the system, but it does not work. Flash also does not seem to be working in IEcapt, and it has no flags for enabling plugins, so I am assuming the functionality is not there either.
Does anyone have any thoughts on how you could render something like an /index.jsp to an image from a Windows or Linux command line?
Selenium webdriver might be useful here:
http://docs.seleniumhq.org/projects/webdriver/
It is used primarily for test automation but it might be helpful.
It could be used, for example, like this:
import org.openqa.selenium.*;
WebDriver driver = new FirefoxDriver(); // create a Firefox webdriver instance
driver.get("http://www.google.com/"); // navigate to page
File screenshotFile = ((Screenshot)driver).getScreenshotAs(file); // capture screenshot
// and save to a file
// here you can trigger any necessary actions on the website:
Webelement element = driver.findElement(By.name("q")).sendKeys("xxxxx");
element.click();
new WebDriverWait(driver, 10)).until(ExpectedConditions.titleContains("xxxxx"));
// and capture a new screenshot once the content has changed
File xxxScreenshotFile = ((Screenshot)driver).getScreenshotAs(file);
Have you tried using java.awt.Robot?
Rectangle rect = yourGragphicsConfiguration.getBounds();
BufferedImage image = new Robot().createScreenCapture(rect);
If you know the position of your applet you might be able to get it with
BufferedImage dest = image.getSubimage(appletX, appletY, appletHeight, appletWidth);
You can take a screenshot of Swing/AWT component.
This can be done in 2 ways. In both cases the component must be visible.
Without the robot use:
BufferedImage image = new BufferedImage(component.getWidth(),
component.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
component.paint(g);
With the robot use:
In this case the screenshot of area in which this component is situated will be made. That is, if the component overlaps another application window then the screenshot will contain an area of this another window.
Point point = new Point(0, 0);
SwingUtilities.convertPointToScreen(point, component);
Rectangle region = component.getBounds();
region.x = point.x;
region.y = point.y;
BufferedImage image= new Robot().createScreenCapture(region);
This information is taken from the article: Frequently Asked Questions during Java applet development

Render and Export FusionCharts on the Server

I am trying to render and export FusionCharts completely on the server. I am aware of solutions such as FCimg and FusionCharts .NET Solution. I have also implemented a Java solution that uses the Process class to run wkhtmltoimage.
However, I am trying to find a pure Java solution of doing this. I have an html file that includes FusionCharts JS Libraries and code to generate the fusion chart. I found JxBrowser that properly renders the chart but it requires X-Server for it to work on Linux. I also have tried Cobra/Lobo Browser but it does not fully support JavaScript. Are there any other ways to render and export fusion charts on the server or atleast render an html file that includes JavaScript completely in Java (and that does not require xserver)?
Thanks in advance for all the help!
Update: Solution that does not require xserver: WebRenderer. The Swing Edition is the only edition that supports HTML5 as of July 9th, 2012. You can use the swing edition to capture the image without a GUI.
I found a way that uses Eclipse's SWT Browser. However this cannot be run in an headless mode. You will have to use xserver to implement this. See this question.
Since this requires xserver and cannot be run in an headless mode, I would suggest using JxBrowser. It is a lot simpler and all you need is to generate an html file with all the fusion charts scripts. See #1, #2, #3
You have to create a template.html file that contains the header
(<html><head>), jquery.min.js, FusionCharts.js,
FusionCharts.HC.js, FusionCharts.HC.Charts.js. Make sure each of
these scripts are in their own script tags (<script type="text/javascript"> [js code] </script>)
Now add another JavaScript function with its own script tags containing the steps to render the chart. For example:
function load() { FusionCharts.setCurrentRenderer('javascript'); var chart = new FusionCharts("swf", 'chart0', "width", "height", "0", "1"); chart.setXMLData("XML DATA HERE"); chart.render("divNAMEHere"); }
Now you need to call the load() function onload, create a div to render the chart in, and end the html file. For example:
`
test
`
Create a new class that imports the eclipse swt browser libraries. Instantiate Display, Shell, and Browser (use this as a guideline to help understand what is happening: http://www.roseindia.net/tutorials/swt/swt-browser.shtml).
Set the text of the browser (browser.setText("htmlcode")) to the html code from template.html. The best way to do this would be to read the file using BufferedReader.
Lastly, the image takes some time to render. Now there is probably a better way to do this but if you want to just get it working, I set up a count and it captures the image after a certain number. This is what you need to add to the end:
int i = 0;
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
i++;
// System.out.println(i);
if(i==100)
{
GC source = new GC (shell);
Image image = new Image(display, browser.getClientArea());
source.copyArea(image, 0, 0);
ImageLoader io = new ImageLoader ();
io.data = new ImageData[] { image.getImageData() };
File f = new File (currentDir+"/workpng.png");
io.save (f.getAbsolutePath(), SWT.IMAGE_PNG);
}
}
}

Vaadin framework play video

Can I play video using Vaadin framewotk ?
The main idea is loading video files from local drive in flv or avi formats and play it in web using vaadin framework.
Thanks.
There is a sample in the Sampler: http://demo.vaadin.com/sampler/#FlashEmbed
You can see the source by clicking 'view source', and it will show you something like this:
Embedded e = new Embedded(null, new ExternalResource(
"http://www.youtube.com/v/meXvxkn1Y_8&hl=en_US&fs=1&"));
e.setMimeType("application/x-shockwave-flash");
e.setParameter("allowFullScreen", "true");
e.setWidth("320px");
e.setHeight("265px");
addComponent(e);
Obviously, you'll want to change the ExternalResource to something else (e.g FileResource, ClassResource, StreamResource, ...) in order to play local files.
Vaadin version 6.7 brought a new class Video that uses the new HTML5 "video" element to embed video on a page.
My posting on the Vaadin Forum provides the source code for an example app.
The main part of that code, when populating a window or layout:
Video v = new Video( "video" ); // Instantiate video player widget.
// Specify a list of your video in one or more formats.
// Different browsers support various different video formats.
v.setSources(
new ExternalResource( "http://www.example.com/media/example_video.mp4" ),
new ExternalResource( "http://www.example.com/media/example_video.ogv" )
);
v.setWidth( "640px" ); // Set size of the video player's display area on-screen.
v.setHeight( "360px" );
this.addComponent( v ); // Add the component to the window or layout.
Oops, I just re-read you posting -- you want to play local video files. Do you mean local to the user's computer or the Vaadin app server-side computer? Either way, you may be able to manipulate the "ExternalResource" seen above, or another subclass of Vaadin Resource to access a local file.
You can use the Embedded Class to embed videos.
NOTE: This is for local files:
FileResource fileResource = new FileResource(new File("/Users/user/Downloads/DBTI_1991_teaser_HD.mp4"));
Video vd = new Video();
vd.setAutoplay(true);
vd.setSource(fileResource);
this.addComponent(vd);
Another alternative is the Vaadin add-on "YouTubePlayer" if you want to access a video specifically from YouTube.com.

Categories