12

I use CrossWalk to display webpage, it works well. I have a feature to capture the whole content as bitmap to save into SDCard, but I cannot found a solution. Using TextureView can only capture a screen size bitmap, anyone has the same issue? BTW, I can capture the whole content using WebView.draw().

handrenliang
  • 1,047
  • 1
  • 10
  • 21

3 Answers3

3

Here's some pseudo code that may help. You can get the content height and width from the webview and then you can leverage webview.draw()...so something like the following.

Bitmap  bitmap = Bitmap.createBitmap( webView.getWidth(), webView.getContentHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);

Then you can output your bitmap file using bitmap.compress and output it to a file output stream

//fos is a FileOutputStream, you can use something else if needed. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);

The only issue I foresee with this is that your bitmap may clip the content horizontally since WebView doesn't have a method to get the content width. Otherwise I think this should work.

Developer Paul
  • 1,502
  • 2
  • 13
  • 18
  • I use this method to capture WebView content, but it doesn't work on CrossWalk WebView. – handrenliang Jun 25 '15 at 01:59
  • I'm not familiar with cross walk but looking at their documenation it's clear this won't work. So sorry about that. The XWalkView is a subclass of FrameLayout, not web view. Is there anything preventing you from loading your html to a webview and saving it from there? – Developer Paul Jun 25 '15 at 02:06
  • As you known, WebView below 4.4 use Webkit to render page, it sucks. I create a hypertext editor that doesn't work well below 4.4. – handrenliang Jun 25 '15 at 02:26
  • Is it possible to make the html content fit to the size of the users screen and then use conventional methods to save a bitmap like you would in a view? If you can fit the content to the screen then you should in theory be able to fit everything into the picture. – Developer Paul Jun 29 '15 at 20:43
  • this doesn't capture the invisible part of webview which need to scroll – Mneckoee Nov 17 '16 at 05:25
3

I never using crosswalk before, but I'm guessing the Crosswalk WebView is also descendant from android.view.View. If so, then you could use android view drawing cache. It look like this

yourWebView.setDrawingCacheEnabled(true);
Bitmap bmp = yourWebView.getDrawingCache();

Then as Paul said, save it through FileOutputStream

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fchristysen
  • 208
  • 1
  • 10
2

You can't capture XWalkView image by standard ways as described in answers above because Crosswalk XWalkView works with hardware layer (i.e. SurfaceView or TextureView). But you can use getBitmap() method of TextureView class to get it.

In short, you should enable using of TextureView in Crosswalk before XWalkView will be initialized (in Application subclass for example) with:

XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);

And find TextureView in views tree to call getBitmap() on it.

Something like that:

/**
    * Returns TextureView which is used in XWalkView
    *
    * @param group
    * @return
    */
private TextureView findXWalkTextureView(ViewGroup group) {
    int childCount = group.getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = group.getChildAt(i);
        if (child instanceof TextureView) {
            String parentClassName = child.getParent().getClass().toString();
            boolean isRightKindOfParent = (parentClassName.contains("XWalk"));
            if (isRightKindOfParent) {
                return (TextureView) child;
            }
        } else if (child instanceof ViewGroup) {
            TextureView textureView = findXWalkTextureView((ViewGroup) child);
            if (textureView != null) {
                return textureView;
            }
        }
    }

    return null;
}

/**
    * Example of capturing image from XWalkView based on TextureView
    *
    * @return
    */
public Bitmap captureImage() {
    if (mXWalkView != null) {
        Bitmap bitmap = null;

        boolean isCrosswalk = false;
        try {
            Class.forName("org.xwalk.core.XWalkView");
            isCrosswalk = true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (isCrosswalk) {
            try {
                TextureView textureView = findXWalkTextureView(mXWalkView);
                bitmap = textureView.getBitmap();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            bitmap = Bitmap.createBitmap(mXWalkView.getWidth(), mXWalkView.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(bitmap);
            mXWalkView.draw(c);
        }

        return bitmap;
    } else {
        return null;
    }
}

Check this code: https://github.com/gitawego/cordova-screenshot/blob/master/src/android/Screenshot.java for more details.

comrade
  • 4,590
  • 5
  • 33
  • 48