13

I have a custom WebView and I want to get a bitmap of its content (offscreen included). I used this code, which I got from here:

 public static Bitmap getBitmapFromWebviewV2(WebView webView) {
    webView.measure(View.MeasureSpec.makeMeasureSpec(
        View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
        View.MeasureSpec.makeMeasureSpec(0, View.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);
    webView.draw(bigcanvas);
    return bm;
}

It works fine up to the point when I zoom in a lot, in which case I get OutOfMemory Crash. I tested this with the same picture (slightly zoomed and zoomed to the max) and it behaves in the same way I mentioned above.

I tried to counter this by adding

while(webView.canZoomOut()){
      webView.zoomOut();
}

at the start, but it doesn't help at all.

Oleksandr Firsov
  • 1,428
  • 1
  • 21
  • 48

2 Answers2

0

Okay, I've cracked this one meself. The problem indeed was in the fact that the function returned the Bitmap waay before the zooming out procedure was over, so I had to delay it.

I incorporated

Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //bulk of my code
            }
        }, 1000);

which forced to change the structure of the function from public Bitmap to public void. Here's directly related thread. Despite some minor tweaks I still need to fix, the approach works like a charm

Oleksandr Firsov
  • 1,428
  • 1
  • 21
  • 48
  • So, why don't you directly get the original dimensions of your `WebView` before it's zoomed in and use `Bitmap.createScaledBitmap()`, using the original dimensions as target dimensions for the `Bitmap`? – Danail Alexiev Aug 17 '17 at 10:47
  • @Oleksandr Firsov , are you sure you did not get any out of memory by using handler. – Chetan Joshi Aug 18 '17 at 12:35
  • @Chestan Joshi Nope, tested it quite a few times with different images and no errors. – Oleksandr Firsov Aug 20 '17 at 11:56
-1

Quick fix:-

Set android:largeHeap="true" in your AndroidManifest.xml file.

<application
    android:name="yourapplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher_rounded"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:roundIcon="@mipmap/ic_launcher_rounded"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

Gud luck :)

Satwinder Singh
  • 627
  • 1
  • 6
  • 23
  • This flag is often ignored and even in case of large heap, you still have a possibility to get OOM when creating a bitmap. – Dimezis Aug 18 '17 at 10:50