在Android中从HTML生成位图

如何从Android中的HTML生成位图

WebView可以用于这个还是有一个更好的方法(如可能直接使用WebView渲染引擎)? 怎么样?

我想实施以下方法…

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

…其中html是要呈现的html,而rect是所需位图的框架。

Solutions Collecting From Web of "在Android中从HTML生成位图"

一种使用WebView从HTMLstring生成位图的同步方法,可以在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; } 

它有一些限制,但这是一个开始。

您可以使用绘制方法让它在您select的位图中绘制。 我举了一个例子,不要忘记你的清单的networking和外部存储权限:

 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); } }

为什么不使用WebView方法:capturePicture()返回一个Picture并且从API级别1开始可用?

它返回整个文档的图片。

然后,您可以裁剪矩形的结果,并从那里保存位图。

这个例子展示了如何捕获webView内容的最后一张图片(它一直等到webview完成渲染图片),这是一个使用Android将HTML转换为PNG的例子

活动代码

 public class HtmlViewer extends Activity { private String HTML; private Context ctx; private Picture pic = null; private int i=0; suppose this is the last pic private int oldi = 0; private Timer myTimer; // timer for waiting until last picture loaded @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_html_viewer); Intent intent = getIntent(); HTML = intent.getStringExtra("HTML"); ctx = this; WebView wv = (WebView)findViewById(R.id.webView1); wv.setPictureListener(new PictureListener(){ public void onNewPicture(WebView view, Picture picture) { Log.w("picture", "loading.." + String.valueOf(view.getProgress())); pic = picture; i++; } }); wv.loadData(HTML, "text/html; charset=utf-8", null); wv.setWebViewClient(new WebViewClient() { public void onPageFinished(WebView wv, String url) { Picture p = wv.capturePicture(); myTimer = new Timer(); myTimer.schedule(new TimerTask() { @Override public void run() { if (i > oldi) oldi = i; else if (i != 0) { Log.w("picture", "finished"); cancel(); Picture picture = pic; Log.w("picture", "onNewPicture- Height"+ picture.getHeight()); Log.w("picture", "onNewPicture- Width"+ picture.getWidth()); File sdCard = Environment.getExternalStorageDirectory(); if (picture != null) { Log.w("picture", " P OK"); Bitmap image = Bitmap.createBitmap(picture.getWidth(),picture.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(image); picture.draw(canvas); Log.w("picture", "C OK"); if (image != null) { Log.w("picture", "I OK"); ByteArrayOutputStream mByteArrayOS = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.PNG, 90, mByteArrayOS); try { File file = new File(sdCard, "AccountView.PNG"); FileOutputStream fos = new FileOutputStream(file); fos.write(mByteArrayOS.toByteArray()); fos.flush(); fos.close(); Log.w("picture", "F OK " + String.valueOf(mByteArrayOS.size()) + " ? " + String.valueOf(file.length())); Intent sharingIntent = new Intent(Intent.ACTION_SEND); Uri screenshotUri = Uri.fromFile(file); sharingIntent.setType("image/png"); sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri); startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.ACCOUNT_VIEW_TITLE))); ((Activity)ctx).finish(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } } } }, 0, 1000); Log.w("picture", "done"); loadcompleted = true; } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_html_viewer, menu); return true; } } 

布局

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".HtmlViewer" > <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="match_parent" />