Snapshot the webview return blank image - android

I want to snapshot the entire of the content of the WebView. However, the returned image is always blank. Can you take a look and tell me where I'm wrong.
Please don't suggest me use capturePicture function because the function is deprecated at this time.
Some codes
public class WebViewActivity extends Activity {
private static WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
webView = (WebView) findViewById(R.id.webView1);
webView.loadUrl("http://developer.android.com/training/basics/firstapp/creating-project.html");
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
webView.measure(MeasureSpec.makeMeasureSpec(
MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
webView.layout(0, 0, webView.getMeasuredWidth(),
webView.getMeasuredHeight());
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache();
Bitmap bm = Bitmap.createBitmap(webView.getMeasuredWidth(),
webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas bigcanvas = new Canvas(bm);
Paint paint = new Paint();
int iHeight = bm.getHeight();
bigcanvas.drawBitmap(bm, 0, iHeight, paint);
if (bm != null) {
try {
String path = Environment.getExternalStorageDirectory()
.toString();
OutputStream fOut = null;
File file = new File(path, "/aaaa.png");
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
bm.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
The layout.xml
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Thank you very much!!!

I found out the solution. Take a look of this.
I used the onDraw to replace the capturePicture functon which is deprecated in API 19. If you have any better solutions, please tell me and I appreciate that. Thanks!
Which can replace capturePicture function

Related

Android Webview, trying to save as image file only seems to store a blank image

I must be doing something wrong here with saving the image or something, as when I save it as a png, its a blank white image. When I save it as a JPEG, it's a blank black image.
The webview loads in my application after about 1 second.
.....
webView = (WebView)findViewById(R.id.webview_1);
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
//Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Bitmap b = getBitmapFromWebView(webView);
Canvas c = new Canvas(b);
view.draw(c);
try {
FileOutputStream fos = openFileOutput("test.png", Context.MODE_APPEND);
//fos = new FileOutputStream( "/sdcard/" + "page.jpg" );
if ( fos != null ) {
b.compress(Bitmap.CompressFormat.PNG, 90, fos );
fos.close();
}
}
catch( Exception e ) {
System.out.println("-----error--"+e);
}
}
});
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
webView.loadUrl("file:///android_asset/World_display.html");
....
public Bitmap getBitmapFromWebView(WebView wv) {
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(wv.getDrawingCache());
webView.setDrawingCacheEnabled(false);
return bitmap;
}
Please try this:
public static Bitmap getBitmapfromView(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
return bitmap;
}
As it turns out, the webview isn't rendered until sometime after onPageFinished. All of this code being in my onCreate was saving a blank image because the webview hadn't been rendered yet.
Ended up doing this as a separate method outside onCreate:
public Bitmap getBitmapFromWebView(View v) {
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
try {
FileOutputStream fos = openFileOutput("test.png", Context.MODE_PRIVATE);
//fos = new FileOutputStream( "/sdcard/" + "page.jpg" );
if (fos != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
}
} catch (Exception e) {
System.out.println("-----error--" + e);
}
return bitmap;
}
And calling this method from within a "submit" button onclick in the onCreate.

Webview unusable after draw method called

I want to extract webview screenshot (even if there is a scroll) and to save it.
My problem is after webview.draw() method called, webview is now an image an is unusable as a webview.
If there a way to prevent that behavior ?
Important : I can't just reload webview because user enters fields.
Here's my code :
protected void onClicked() {
mWebView.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
mWebView.layout(0, 0, mWebView.getMeasuredWidth(),
mWebView.getMeasuredHeight());
mWebView.setDrawingCacheEnabled(true);
mWebView.buildDrawingCache();
generateWebViewCapture();
}
/**
* Create capture of all webview.
*/
#Background
void generateWebViewCapture() {
Bitmap bm = Bitmap.createBitmap(mWebView.getMeasuredWidth(),
mWebView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
Paint paint = new Paint();
int iHeight = bm.getHeight();
canvas.drawBitmap(bm, 0, iHeight, paint);
mWebView.draw(canvas);
runOnUiThread(new Runnable() {
#Override
public void run() {
mWebView.setDrawingCacheEnabled(false);
mWebView.invalidate();
}
});
try {
String path = getReportPath();
File file = new File(path, "/report-"+System.currentTimeMillis()+".png");
OutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT :
To fix the problem, remove that line :
mWebView.layout(0, 0, mWebView.getMeasuredWidth(),
mWebView.getMeasuredHeight());
Just mWebView.setDrawingCacheEnabled(false) after you get the bitmap!
mWebView.setDrawingCacheEnabled(true);
// remove mWebView.buildDrawingCache();
Bitmap bm= mWebView.getDrawingCache();
//remove generateWebViewCapture();
try {
String path = getReportPath();
File file = new File(path, "/report-"+System.currentTimeMillis()+".png");
OutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
mWebView.setDrawingCacheEnabled(false);
This code is worked on my mobile:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testm);
final WebView mWebView = (WebView) findViewById(R.id.webview);
mWebView.loadUrl("http://www.csdn.net/");
findViewById(R.id.iv_0).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mWebView.setDrawingCacheEnabled(true);
// remove mWebView.buildDrawingCache();
Bitmap bm= mWebView.getDrawingCache();
//remove generateWebViewCapture();
try {
String path = getFilesDir().getPath();
File file = new File(path, "/report-"+System.currentTimeMillis()+".png");
OutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
mWebView.setDrawingCacheEnabled(false);
}
});
}
}
It does not work on Android R.
WebView.enableSlowWholeDocumentDraw()
Add ScrollView, It works.
<ScrollView
android:layout_marginStart="#dimen/margin_8"
android:layout_marginEnd="#dimen/margin_8"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/web_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>

Generate bitmap from view

When I get the bitmap from the DrawingCache of a view I get no error but I don't see a valid bitmap either. What am I doing wrong?
The code I use to generate the bitmap:
SharePhotoView sharePhotoView = SharePhotoView_.build(this);
sharePhotoView.bind(mCatch);
sharePhotoView.setDrawingCacheEnabled(true);
sharePhotoView.buildDrawingCache();
Bitmap bitmap = sharePhotoView.getDrawingCache();
catchImage.setImageBitmap(bitmap);
The code I use to make the view:
#EViewGroup(R.layout.share_photo)
public class SharePhotoView extends LinearLayout{
#ViewById
ImageView catchImage;
public SharePhotoView(Context context) {
super(context);
}
public void bind(Catch catchItem) {
Bitmap bitmap = BitmapFactory.decodeFile(catchItem.getImage().getPath());
catchImage.setImageBitmap(bitmap);
}
}
Use this code for a Bitmap from view:
Bitmap bitmap;
try {
bitmap = Bitmap.createBitmap(YOUR_VIEW.getWidth(), YOUR_VIEW.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
YOUR_VIEW.draw(canvas);
File root = Environment.getExternalStoragePublicDirectory(Environment.PICTURES);
String fname = "NAME_OF_FILE.jpg";
file = new File(root, fname);
try {
if (!root.exists()) {
root.mkdir();
}
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
YOUR_VIEW.destroyDrawingCache();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
Found a method somewhere that did the trick:
public static Bitmap getScreenViewBitmap(View v) {
v.setDrawingCacheEnabled(true);
// this is the important code :)
// Without it the view will have a dimension of 0,0 and the bitmap will be null
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
Source: http://www.jattcode.com/getting-bitmap-from-a-view-visible-invisible-oncreate/

After saving webview as file not loading completely in android

I want to generate bitmap for webview full page.
some codes
Below code for generating Bitmap from webview
Webview to Bitmap :
webview.measure(MeasureSpec.makeMeasureSpec(
MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
webview.layout(0, 0, webview.getMeasuredWidth(),
webview.getMeasuredHeight());
webview.setDrawingCacheEnabled(true);
webview.buildDrawingCache();
Bitmap bm=null;
try
{
Log.d("Measuredwidth", "MeasuredWidth"+webview.getMeasuredWidth());
Log.d("Measuredheight", "Measuredheight"+webview.getMeasuredHeight());
Log.d("Measuredheightandstate", "Measuredheight and state"+webview.getMeasuredHeightAndState());
bm = Bitmap.createBitmap(webview.getMeasuredWidth(),
webview.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
return null;
}
Canvas bigcanvas = new Canvas(bm);
Paint paint = new Paint();
int iHeight = bm.getHeight();
bigcanvas.drawBitmap(bm, 0, iHeight, paint);
webview.draw(bigcanvas);
below code for to save the file in memory for that
To save as file :
if (bm != null) {
try {
String path = Environment.getExternalStorageDirectory()
.toString();
OutputStream fOut = null;
File file = new File(path, "/aaaa.png");
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 50, fOut);
fOut.flush();
fOut.close();
bm.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
Here my problem is webview loading completely but after saving as file bottom half not completely loading .
i tried to get solution for this but failed.
if any one have idea about this please help me.. Thanks in adavance

webView.getMeasuredWidth() and getMeasuredHeight() not work on API before 4.4.X

i have this code for my WebView
public static void loadHtml (final Context ctx) {
final WebView webView = new WebView(ctx);
//runnable and 2s delay is set because i load some javascript in onPageFinished
//i omitted it for semplicity
final Handler mHandler = new Handler();
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//call some javascript in webView ...
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
webView.measure(MeasureSpec.makeMeasureSpec(
MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache();
//take webview screenshot loaded with a pdf/html
takeScreenShot(ctx, webView);
}
}, 2000);
}
webView.loadUrl("file:///android_asset/" + folder + "/index.html");
}
public static void takeScreenShot(Context ctx, WebView webView){
Bitmap bm = Bitmap.createBitmap(webView.getMeasuredWidth(), //<-- WHERE IT BREAKS
webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas bigcanvas = new Canvas(bm);
Paint paint = new Paint();
int iHeight = bm.getHeight();
bigcanvas.drawBitmap(bm, 0, iHeight, paint);
webView.draw(bigcanvas);
if (bm != null) {
try {
OutputStream fOut = null;
fOut = new FileOutputStream(imageTemp);
bm.compress(Bitmap.CompressFormat.JPEG, 50, fOut);
fOut.flush();
fOut.close();
bm.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When i run this code on a Samsung Galaxy tab 10.1 with Android 4.4.2 everything works fine, but when i run it in an Asus Transformer with Android 4.2.1 webView.getMeasuredWidth() and webView.getMeasuredHeight() return 0 and an Exception is thrown: "width and height must be > 0"
i read a lot of topics about this problem on SO, but everythin i tried didn't solve my problem. i wish to provide my app to API 17 customers too, and not only starting from 19...
Someone with a solution? thanks :)
Seems to be no solutions with WebView lower than 4.4.X
The only thing which worked for me is to place an hidden WebView in the XML layout, and in loadHtml method i'm checking the Android Version
Example Code:
final WebView webView;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
webView = new WebView(ctx);
else {
webView = (WebView)findViewById(R.id.hidden_webview);
webView.setVisibility(View.VISIBLE);
}
and in the second case, i remove this code from the inner run method
webView.measure(MeasureSpec.makeMeasureSpec(
MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache();
Hope could help someone, sorry for late answer

Categories

Resources