Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Take screenshots og your app!
I'm happy to announce the Html2Canvas add-on which allows you to take an actual screenshot of your application and receive the image on your server for doing with as you please. A good use case is for support where your users can trigger a screenshot of the app to show you what they are seeing. The add-on can be downloaded from https://vaadin.com/directory#!addon/html2canvas-screenshot
Hello , I congratulate you for excellent plug -in
I get error in implementing its basic example in vaadin 7.5.8 error org/apache/commons/codec/binary/Base64 in (Screenshot.java:94), (Screenshot.java:78) (Screenshot.java:26) and (Screenshot.java:37).
using java 8
thanks
// Initialize our new UI component
final Screenshot component = new Screenshot();
component.addScreenshotListener(new ScreenshotListener() {
public void screenshotComplete(ScreenshotImage image) {
showImageInWindow(image);
}
});
// Show it in the middle of the screen
final VerticalLayout layout = new VerticalLayout();
//layout.setStyleName("demoContentLayout");
layout.setSizeFull();
layout.addComponent(component);
final Button button = new Button("Take Screenshot", new Button.ClickListener() {
public void buttonClick(Button.ClickEvent event) {
component.takeScreenshot();
}
});
layout.addComponent(button);
layout.setComponentAlignment(button, Alignment.TOP_CENTER);
final Button button2 = new Button("A screenshot of me!");
final Screenshot targetScreenshot = new Screenshot();
targetScreenshot.addScreenshotListener(new ScreenshotListener() {
public void screenshotComplete(ScreenshotImage image) {
showImageInWindow(image);
}
});
targetScreenshot.setTargetComponent(button2);
button2.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
targetScreenshot.takeScreenshot();
}
});
layout.addComponent(targetScreenshot);
layout.addComponent(button2);
layout.setComponentAlignment(button2, Alignment.TOP_CENTER);
setContent(layout);
By clicking on the button , the error
feb 16, 2016 3:01:02 PM com.vaadin.server.DefaultErrorHandler doDefault
GRAVE:
java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64
at org.vaadin.addons.screenshot.Screenshot.parse(Screenshot.java:94)
at org.vaadin.addons.screenshot.Screenshot.parseAndNotify(Screenshot.java:78)
at org.vaadin.addons.screenshot.Screenshot.access$000(Screenshot.java:26)
at org.vaadin.addons.screenshot.Screenshot$1.screenshotResult(Screenshot.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:313)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:202)
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:95)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:351)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
you are missing commons-codec from your classpath. maven should have pulled it in for you. if you're not using maven you need to add commons-codec to classpath yourself. i tested version 1.6 with the add-on
excellent , now I click on the button and does nothing.
the action does not run when I click
sorry for my English
Hi!
I was very excited to find your add-on and am really looking forward to taking my first screenshots. I don't know why, but somehow I can't get your add-on to work. After failing within my complex project, I tried to get it to run with this simple dummy-project:
@Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
final Screenshot screenshot = new Screenshot();
screenshot.addScreenshotListener(new ScreenshotListener() {
public void screenshotComplete(ScreenshotImage image) {
Window window = new Window("Here's your screenshot", new Image(null, new ExternalResource(image.getDataURL())));
window.setWidth("80%");
window.setHeight("80%");
addWindow(window);
}
});
Button button = new Button("Click Me");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
screenshot.takeScreenshot();
}
});
layout.addComponent(button);
}
The compiler does not have any errors, but the method screenshotComplete is never invoked.
Could you give me any pointers in how to use your add-on or what I'm doing wrong? The complete dummy project is attached, if that helps.
Thank you!
You have not added the screenshot component to your layout.
thank you for the fast reply. Now I am getting the following error message on the screen:
"Widgetset 'com.vaadin.DefaultWidgetSet' does not contain implementation for org.vaadin.addons.screenshot.Screenshot. Check its component connector's @Connect mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions".
I have rebuilt the whole project and nothing has changed. I only added the add-on dependency to my ivy.xml. Do I need to do something else? Sorry, I am not that experienced with including add-ons.
Yes, you must compile a custom widgetset and include <inherits name="org.vaadin.addons.screenshot.WidgetSet" />. See the demo project in GitHub.
works like a charm :)
Thank you, your fast help made my day!
Hello Mark A Thomas ! Good job for you add on. Your add on works perfectly, except when I want to make a screenshot of my map (openLayer). I have an error :
SecurityError: The operation is insecure
window.html2canvas/options.complete
start
setImageLoadHandlers/img.onload
I am using OpenLayer and Geoserver to display my map. When I remove the map, your add works well. What must I do ? thanks !
PS : this error is only occuring on Firefox and Chrome. On IE, I have no problem ! I need use those 3 browsers.
I'm afraid I do not have an answer for you to this SecurityError. I have never seen that before.
This is an error about CORS (Cross origin). The map that I display comes from another domain, so when I press screenshot, my method "ScreenshotComplete" is never invoked, and the error above show up ! except on IE. Someone has an idea ? thanks :) !
Hello!
I have a very large component, when I make a screenshot, then captured the width equal to the width of the screen, the remaining space is white.
What could be the problem?
I am able to use your plugin to capture a screenshot. However, it does not capture my svg components which were created using Google Charts. The other components of the page are captured correctly. Any suggestions?
You're not the first person to mention this and although I have not looked into it I can conjecture that the charts may not be part of the main DOM. Additionally, If they're SVG charts the the html2image library probably doesn't know how to render them.
It looks like the next release willl support SVG rendering. It is currently in alpha status at https://github.com/niklasvh/html2canvas/releases
Thanks for the response. I did pull down the latest version of html2canvas and the SVG rendering still did not work. However, I was able to use the solution described here to use canvg.js to pre-render the SVG's onto a canvas object. By doing this I am able to render my SVG objects in the final output image.
Also, I saw some comments requesting the ability to capture a single component rather than the entire screen. I was able to do this using the Screenshot's Builder class.
Screenshot screenshot = Screenshot.newBuilder().ofTargetComponent(myComponent).build();
This successfully renders only the requested component, however the size of the image is equal to the size of the parent window. This might be the issue to which Evgeny was referring above.
Great product, thanks for making it available.
Hi,
I 'm trying to get your demo working, but it failed: [ERROR] No plugin found for prefix 'jetty' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories....
I have downloaded your project from github, Opened it in eclipse and choose Run as -> Maven build using the Goals clean install jetty:run
Any idea's?
My guess is the version of Jetty used in the project is too old. Are you testing the Vaadin 7 or Vaadin 8 version of the plug-in?
Hi mark,
I just figured out I must add the org.mortbay.jetty plugin group to C:\Users....m2\settings.xml :
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>${user.home}/.m2/repository</localRepository>
<interactiveMode>true</interactiveMode>
<usePluginRegistry>false</usePluginRegistry>
<offline>false</offline>
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
</settings>
Now I don't understand how to run it from eclipse. I use the maven goals : clean install jetty:run
Jetty runs but it gives a 404 page using http://localhost:8080/screenshot-demo/ or http://localhost:8080
I also tried to run the maven goals: clean install cd demo jetty:run But this gives the error: Unknown lifecycle phase "cd". You must specify a valid lifecycle phase or a goal in the format.
You shouldn't have to add anything to settings.xml. I just opened the project and replicated the issue. Even tried updating the Jetty plugin and it still fails. As for your error, you have run mvn clean install
then run cd demo
then run mvn jetty:run
I want to use it in a Vaadin 8 project. So I tried to change the vaadin version in the pom.xml files in your demo project.
I have changed <vaadin.version>8.5.0</vaadin.version> in screenshot-demo/pom.xml
and screenshot/pom.xml
. I also removed this.setImmediate(true); in Screenshot.java
Then run mvn clean install
then run cd screenshot-demo
then run mvn jetty:run
This results in the next error:
[WARNING] Problem processing jar entry com/vaadin/data/Result.class
java.lang.ArrayIndexOutOfBoundsException: 51966
at org.objectweb.asm.ClassReader.readUTF8 (Unknown Source)
at org.objectweb.asm.ClassReader.readClass (Unknown Source)
at org.objectweb.asm.ClassReader.accept (Unknown Source)
at org.objectweb.asm.ClassReader.accept (Unknown Source)
at org.eclipse.jetty.annotations.AnnotationParser.scanClass (AnnotationParser.java:899)
at org.eclipse.jetty.annotations.AnnotationParser$2.processEntry (AnnotationParser.java:857)
at org.eclipse.jetty.webapp.JarScanner.matched (JarScanner.java:161)
at org.eclipse.jetty.util.PatternMatcher.matchPatterns (PatternMatcher.java:100)
at org.eclipse.jetty.util.PatternMatcher.match (PatternMatcher.java:82)
at org.eclipse.jetty.webapp.JarScanner.scan (JarScanner.java:84)
at org.eclipse.jetty.annotations.AnnotationParser.parse (AnnotationParser.java:869)
at org.eclipse.jetty.annotations.AnnotationParser.parse (AnnotationParser.java:884)
at org.eclipse.jetty.annotations.AnnotationConfiguration.parseWebInfLib (AnnotationConfiguration.java:422)
at org.eclipse.jetty.annotations.AnnotationConfiguration.configure (AnnotationConfiguration.java:120)
at org.eclipse.jetty.webapp.WebAppContext.configure (WebAppContext.java:468)
at org.eclipse.jetty.webapp.WebAppContext.startContext (WebAppContext.java:1237)
at org.eclipse.jetty.server.handler.ContextHandler.doStart (ContextHandler.java:717)
at org.eclipse.jetty.webapp.WebAppContext.doStart (WebAppContext.java:494)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart (JettyWebAppContext.java:298)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart (HandlerCollection.java:229)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart (ContextHandlerCollection.java:172)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart (HandlerCollection.java:229)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart (HandlerWrapper.java:95)
at org.eclipse.jetty.server.Server.doStart (Server.java:282)
at org.mortbay.jetty.plugin.JettyServer.doStart (JettyServer.java:65)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:64)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty (AbstractJettyMojo.java:520)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute (AbstractJettyMojo.java:365)
at org.mortbay.jetty.plugin.JettyRunMojo.execute (JettyRunMojo.java:523)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
[WARNING] Problem processing jar entry com/vaadin/data/TreeData.class
java.lang.ArrayIndexOutOfBoundsException: 21457
at org.objectweb.asm.ClassReader.<init> (Unknown Source)
at org.objectweb.asm.ClassReader.<init> (Unknown Source)
at org.objectweb.asm.ClassReader.<init> (Unknown Source)
I think it is not compatible with Vaadin 8?
It is most definitely compatible with Vaadin 8. I use it in Vaadin 8 projects. The error you are getting is a Jetty error most likely caused via a version of ASM not compatible with Java 8
Hi Mark,
Before I tried to get your demo working I have added the screenshot add-on dependency and sample code to a button on my app. But there came no screenshot. perhaps you might notice also to add the screenshot component to the layout: ''layout.addComponent( screenshot );''
Now I got it working in our vaadin 8 app. It only shows no icons and it looks different than the original. See attachment. Any idea's?
Unfortunately not. Something might have changed with newer Vaadin versions.
Hi Mark,
I have used this add on to take a screenshot and saved it to a vaadin.ui.Image type. Now, I want to convert this vaadin.ui.Image type to a java.io.File type for further usage. I researched a lot but could'nt find a solution that works for me. Please help!
Sorry, not sure how to do that. I imagine you can get a byte array from it.
Good morning, I am implementing the demo on vaadin 7.6.8 and it does not enter the screenshotComplete, I do not get any error. my code is this:
screenshot = new Screenshot();
screenshot.setTargetComponent(content);
screenshot.addScreenshotListener(new ScreenshotListener() {
public void screenshotComplete(ScreenshotImage image) {
System.out.println(image.getDataURL());
Window window = new Window("Here's your screenshot", new Image(null, new ExternalResource(image.getDataURL())));
window.setWidth("80%");
window.setHeight("80%");
UI.getCurrent().addWindow(window);
window.focus();
}
});
content is a VerticalLayout
the implementation of the button is this
ok = new Button("OK");
ok.addStyleName(ValoTheme.BUTTON_PRIMARY);
ok.setIcon(FontAwesome.CLOUD_UPLOAD);
ok.addClickListener(event->{
screenshot.takeScreenshot();
});
when I click the OK button, it doesn't fire the screenshotComplete event
thanks.
Mark Thomas: I don't see you adding screenshot to the UI.
is taken with screenshot.takeScreenshot() ?
which I have in the "ok" button?
That method only works once the screenshot widget is part of the UI
Perfect, thank you very much. I took the screenshot and save the image, Could you increase the resolution of the screenshot? thanks