Генерация растрового изображения из HTML в Android - PullRequest
10 голосов
/ 08 января 2011

Как вы можете сгенерировать растровое изображение из HTML в Android?

Можно ли использовать WebView для этого или есть лучший подход (как, например, использование механизма рендеринга WebView напрямую)? Как?

Я хотел бы реализовать следующий метод ...

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

... где html - это HTML-код для рендеринга, а rect - фрейм требуемого растрового изображения.

Ответы [ 4 ]

15 голосов
/ 20 января 2011

Синхронный метод, который генерирует растровое изображение из строки HTML с помощью WebView и может использоваться в 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;
}

У него есть некоторые ограничения, но это только начало.

6 голосов
/ 08 января 2011

Вы можете использовать метод draw, чтобы он рисовал в растровом изображении по вашему выбору. Я привел пример, не забывайте права на интернет и внешнее хранилище вашего манифеста:

<code>
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();
      }<br>
      return super.onKeyDown(keyCode, event);
    }
}
0 голосов
/ 15 января 2014

В этом примере показано, как захватить последнее изображение содержимого webView (оно ожидает завершения отрисовки веб-просмотра), это пример преобразования HTML в PNG с использованием Android

Код активности

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" />

0 голосов
/ 18 января 2011

Почему бы не использовать метод WebView: capturePicture (), который возвращает изображение и доступен начиная с уровня API 1?

Возвращает изображение всего документа.

Затем вы можете обрезать результат с помощью прямоугольника и сохранить растровое изображение оттуда.

...