I would like to take a screenshot of a page displayed in a WebView. The page contains flash elements - and here is the problem. When I take a screenshot all the flash parts of the page are blank.
I am using this piece of code to take a screenshot:
WebView webView = (WebView) findViewById(R.id.webview);
Picture picture = webView.capturePicture();
Bitmap screenshot = Bitmap.createBitmap(picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(screenshot);
picture.draw(c);
File file = new File("/sdcard/screenshot.jpg");
FileOutputStream ostream = null;
try {
file.createNewFile();
ostream = new FileOutputStream(file);
screenshot.compress(CompressFormat.JPEG, 90, ostream);
Log.d("Test", "Screenshot taken");
} catch (Exception e) {
Log.e("Test", "Error", e);
} finally {
try {
ostream.close();
} catch (IOException ignore) {
}
}
I was also trying to acquire Bitmap of the screen contents using the solution given in this SO question:
View webView = findViewById(R.id.webview);
Bitmap bitmap = webView.getDrawingCache();
This also doesn't work - the result is the same (i.e. blank flash elements).
So the question is: How to take a screenshot of WebView contents also with flash elements?
Related
I want to take screenshot of my WebView by clicking on menu item . And then I want to draw on this screenshot and save it on my sdcard.
I've also found the solution of taking screenshot and saving. Here it is:
private void getScreen(View content) {
Bitmap bitmap = content.getDrawingCache();
File file = new File("/sdcard/screen.png");
try {
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
and on onOptionsItemSelected() method:
View content = findViewById(R.id.webview_main);
content.setDrawingCacheEnabled(true);
getScreen(content);
It`s work ok, but I want to implement drawing on it too. If anyone know, how to do this, tell me please,
I will be very grateful.
I have drawn some lines on html5 canvas within webview and tried to take screenshot of the webview using below code...
WebView webView = (WebView) findViewById(R.id.webview);
webView.setDrawingCacheEnabled(true);
Bitmap screenshot = Bitmap.createBitmap(webView.getDrawingCache());
webView.setDrawingCacheEnabled(false);
File myFile = new File(Environment.getExternalStorageDirectory().getPath()+ "/myfolder");
if(!myFile.exists()) {
myFile.mkdir();
}
imagePath = myFile.getAbsolutePath() + "/myimage001.png";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imagePath);
if ( fos != null ) {
screenshot.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
}
} catch( Exception e ) {
e.printStackTrace();
}
But when I open that image then it looks empty. Please help.
Do as follows
private void TakeScreenshot()
{
Picture picture = webview.capturePicture();
Bitmap b = Bitmap.createBitmap( picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas( b );
picture.draw( c );
FileOutputStream fos = null;
try {
fos = new FileOutputStream( "mnt/sdcard/yahoo.jpg" );
if ( fos != null )
{
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
}
}
catch( Exception e )
{
}
}
N.B: Take the screenshot after the WebView finishes loading otherwise you will get a blank screen.
I too found taking screenshots of webview displaying a HTML5 canvas directly from android app really unreliable. But there is a workaround -
You can use window.JSInterface.(params) to call an android java function from javascript. You can use canvas.toDataURL() to get a base64 encoded string of the canvas image and use it as the parameter to pass to the function. In the android function, capture the string, decode it and you have the image.
The only caveat is that the canvas area alone will come in as image and not the full device screen. Also, if the canvas didn't have a background color set, the captured png image will have a transparent background. But these can be easily solved by image manipulation from the app code.
E.g. In this game app, the game runs in a HTML5 canvas displayed in a webview. When the game finishes, a "share score" option uses the above technique to capture the canvas image to share.
https://play.google.com/store/apps/details?id=com.skipser.flappytrex
To capture screenshot:
File srcFile= driver.getScreenshotAs(OutputType.FILE);
String filename = UUID.randomUUID().toString();
File targetFile = new File("D:\\Appium\\" + filename + ".png");
FileUtils.copyFile(srcFile, targetFile);
System.out.println(targetFile);enter code here
I want to programatically take screen shot of my game, just as you'd get in Eclipse DDMS.
Screenshot taken through the solution proposed here: How to programmatically take a screenshot in Android? and in most other SO questions only have View elements visible, but not the SurfaceView.
SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get root view
View view = activity.getWindow().getDecorView().getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
// Get current theme to know which background to use
final Theme theme = activity.getTheme();
final TypedArray ta = theme
.obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
// Save the screenshot to the file system
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
+ System.currentTimeMillis() + ".jpg");
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d("ScreenShot", "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Any help in this regard would be highly appreciated. Thanks.
I hope this also useful for you. here little difference for the above answer is
for I used glsurfaceview to take the screen shots hen i click the button.
this image is stored in sdcard for mentioned folder :
sdcard/emulated/0/printerscreenshots/image/...images
My Program :
View view_storelayout ;
view_storelayout = findViewById(R.id.gl_surface_view);
button onclick() {
view_storelayout.setDrawingCacheEnabled(true);
view_storelayout.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(view_storelayout.getDrawingCache());
view_storelayout.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 90, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
final Calendar c=Calendar.getInstance();
long mytimestamp=c.getTimeInMillis();
String timeStamp=String.valueOf(mytimestamp);
String myfile="hari"+timeStamp+".jpeg";
dir_image=new File(Environment.getExternalStorageDirectory()+
File.separator+"printerscreenshots"+File.separator+"image");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "myPath:"
+dir_image.toString(), Toast.LENGTH_SHORT).show();
Log.v("hari", "screenshots:"+dir_image.toString());
}
Note :
But, here i am faced one problem. In this surfaceview , i drawn line and circle
at runtime. after drawn some objects, when i take screenshots , its stored only for
black image like surfaceview is stored as an image.
And also i want to store that surfaceview image as an .dxf format(autocad format).
i tried to stored image file as an .dxf file format.its saved successfully in
autocad format. but, it cant open in autocad software to edit my .dxf file.
The code from the Usman Kurd answer will not work is most cases.
Unless you're rendering H.264 video frames in software with Canvas onto a View, the drawing-cache approach won't work (see e.g. this answer).
You cannot read pixels from the Surface part of the SurfaceView. The basic problem is that a Surface is a queue of buffers with a producer-consumer interface, and your app is on the producer side. The consumer, usually the system compositor (SurfaceFlinger), is able to capture a screen shot because it's on the other end of the pipe.
Take Screenshot of SurfaceView
I used Google chart api to generate the chart using webview in android. Now my next requirement is to save that image into some local storage and to send the image via email and mms.please help me in doing that.
thanks
nishant
WebView w = new WebView(this);
//Loads the url
w.loadUrl("http://www.yahoo.com";);
//After loading completely, take its picture
Picture picture = w.capturePicture();
//Create a new canvas
Canvas mCanvas = new Canvas();
//Draw the Picture into the Canvas
picture.draw(mCanvas);
//Create a Bitmap
Bitmap sreenshot = Bitmap.createBitmap(picture.getWidth(),
picture.getHeight(),Config.ARGB_8888);
//copy the content fron Canvas to Bitmap
mCanvas.drawBitmap(mBitmapScreenshot, 0, 0, null);
//Save the Bitmap to local filesystem
if(sreenshot != null) {
ByteArrayOutputStream mByteArrayOpStream = new
ByteArrayOutputStream();
screenshot.compress(Bitmap.CompressFormat.JPEG, 90,
mByteArrayOpStream);
try {
fos = openFileOutput("yahoo.jpg",
MODE_WORLD_WRITEABLE);
fos.write(mByteArrayOpStream.toByteArray());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
And for sending the images thro email u can go thru this question
and for MMS
I am trying to capture a image of a webview drawn off screen to the user in android and i always end up with a black image. It is the correct size and everything just not the
Here is the code I am using:
String theURL = "file:///android_asset/www/pages/page2.html";
WebView webview = new WebView(ctx);
webview.loadUrl(theURL);
Bitmap bm = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
webview.draw(c);
OutputStream stream = null;
try {
stream = new FileOutputStream(Environment.getExternalStorageDirectory() +"/page.jpg");
bm.compress(CompressFormat.JPEG, 80, stream);
if (stream != null) stream.close();
return new PluginResult(PluginResult.Status.OK);
} catch (IOException e) {
return new PluginResult(PluginResult.Status.ERROR, e.toString());
} finally {
bm.recycle();
}
Thanks if anyone can help.
The webview.loadUrl(theURL); starts the loading of the page, that can take a while. Wait before drawing your webview until after the page is loaded. You can use a setWebViewClient(WebViewClient client) to set up an object to receive notice when the page has finished loading.