Generate bitmap from HTML in Android

How do can you generate a bitmap from HTML in Android?

Can the WebView be used for this or is there a better approach (like maybe using the WebView rendering engine directly)? How?

I would like to implement the following method...

public Bitmap toBitmap(Context context, String html, Rect rect);

...where html is the html to render and rect is the frame of the desired bitmap.


A synchronous method that generates a bitmap from an HTML string using a WebView, and can be used within an AsyncTask:

public Bitmap getBitmap(final WebView w, int containerWidth, int containerHeight, final String baseURL, final String content) {
    final CountDownLatch signal = new CountDownLatch(1);
    final Bitmap b = Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.ARGB_8888);
    final AtomicBoolean ready = new AtomicBoolean(false); 
    w.post(new Runnable() {

        @Override
        public void run() {
            w.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    ready.set(true);
                }
            });
            w.setPictureListener(new PictureListener() {
                @Override
                public void onNewPicture(WebView view, Picture picture) {
                    if (ready.get()) {
                        final Canvas c = new Canvas(b);
                        view.draw(c);
                        w.setPictureListener(null);
                        signal.countDown();
                    }
                }
            });
            w.layout(0, 0, rect.width(), rect.height());
            w.loadDataWithBaseURL(baseURL, content, "text/html", "UTF-8", null);
        }});
    try {
        signal.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return b;
}

It has some limitations, but it's a start.


You can use the draw method to let it draw in a Bitmap of your choice. I made an example, don't forget internet and external storage rights of your manifest:


public class MainActivity extends Activity {
    private WebView mWebView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new WebView(this);
        setContentView(mWebView);
        mWebView.loadUrl("http://tea.ch");
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
      if (keyCode != KeyEvent.KEYCODE_BACK) return super.onKeyDown(keyCode, event);
      Bitmap bm = Bitmap.createBitmap(200, 300, Bitmap.Config.ARGB_8888);
      Canvas c = new Canvas(bm);
      mWebView.draw(c);
      OutputStream stream = null;
      try {
        stream = new FileOutputStream(Environment.getExternalStorageDirectory() +"/teach.png");
        bm.compress(CompressFormat.PNG, 80, stream);
        if (stream != null) stream.close();
      } catch (IOException e) {
      } finally {
        bm.recycle();
      }
return super.onKeyDown(keyCode, event); } }