Android webview takes screenshot only from top of the page
Asked Answered
A

4

6

I am doing a very simple task of taking a screenshot from my webView into a Bitmap... I do it like this:

webView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(webView.getDrawingCache(false));
webView.setDrawingCacheEnabled(false);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);

The problem is that the final bitmap is always showing the top of my web page content! I actually need it to take the screenshot from where I have scrolled the content but this is not simply happening! I have been searching the net for two hours now but no one else seems to have a similar problem. any idea what could have gone wrong?

Ahwaz answered 8/7, 2015 at 14:10 Comment(3)
Do you explicitly want to display the bitmap inside the webView? Or are you doing this just to see what the bitmap shows? If so, try creating a 2nd visible view where you draw the canvas/bitmap.Arria
@Arria I will later save the bitmap as a png file on sdcard. I actually want the screenshot from where the user has scrolled.Ahwaz
Same issue here. If the WebView is scrolled down far enough then I would only get a blank screen in that bitmap. That's obviously an unfortunate bug in WebView.Stockstill
E
3

I guess, this is on Lollipop? If so, make sure you call WebView.enableSlowWholeDocumentDraw() (doc) before your first call to setContentView() that inflates a layout with WebView.

Erotica answered 8/7, 2015 at 21:11 Comment(2)
Nope, not a lollipop thing... I'm testing on android 2.3 and 4.0.2 and have this weird problem.Ahwaz
OK, then what height does your WebView have? You need to set the height of WebView to wrap_content and put it inside a ScrollView. Then you'll get a WebView tall enough to fit your web page, and drawing into a bitmap should now output the entire page.Erotica
M
1

Actually, you don't need the last 2 lines.Just drop them.

webView.setDrawingCacheEnabled(true);  
Bitmap bitmap = Bitmap.createBitmap(webView.getDrawingCache(false));  
webView.setDrawingCacheEnabled(false);

will return the very bitmap you need, from what I've seen.

Massey answered 21/8, 2020 at 20:56 Comment(1)
That works for me, though those APIs are deprecated. Not sure if they are ever planning to remove them.Stockstill
A
0

I came across the same problem and solved it the follwoing way:

First call WebView.enableSlowWholeDocumentDraw() before setContentView(). Then take the screenshot over the whole content of the webview and then crop the bitmap to the actual view size with the desired scroll offset:

// the minimum bitmap height needs to be the view height
int bitmapHeight = (webView.getMeasuredHeight() < webView.getContentHeight())
         ? webView.getContentHeight() : webView.getMeasuredHeight();

Bitmap bitmap = Bitmap.createBitmap(
         webView.getMeasuredWidth(), bitmapHeight, Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);

// prevent IllegalArgumentException for createBitmap: 
// y + height must be <= bitmap.height()
int scrollOffset = (scrollTo + webView.getMeasuredHeight() > bitmap.getHeight())
         ? bitmap.getHeight() : scrollTo;

Bitmap resized = Bitmap.createBitmap(
         bitmap, 0, scrollOffset, bitmap.getWidth(), webView.getMeasuredHeight());
Ayrshire answered 23/8, 2018 at 10:18 Comment(0)
T
0

This worked for me...

First, add webview inside a LinearLayout..

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layoutWeb"
    >
    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webview"/>
</LinearLayout>

Second, initialize views inside onCreate() method...

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    webView = (WebView) findViewById(R.id.webview);
    webLayout = (LinearLayout) findViewById(R.id.layoutWeb);
    ....
 }

Third, write a function to take a screenshot... Here, View v1 = webLayout; specifies the view which we want to take a screenshot of.

public void takeScreenshot() {
  try{   
      View v1 = webLayout;
      v1.setDrawingCacheEnabled(true);
      Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
      v1.setDrawingCacheEnabled(false);
      String mPath = Environment.getExternalStorageDirectory().toString() + "/screenshot.jpg";
      File imageFile = new File(mPath);
      FileOutputStream outputStream = new FileOutputStream(imageFile);
      int quality = 100;
      bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
      outputStream.flush();
      outputStream.close();
 } catch(Throwable e) {
       e.printStackTrace();
  }

This takes a screenshot of the part that is covered by webLayout. Scroll up down to focus on other areas and take screenshot of the webView.

Tincher answered 10/7, 2020 at 1:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.