2012-11-20 25 views
16

有什么方法可以获取某个活动中某个视图的高分辨率的屏幕截图。Android中的高分辨率屏幕截图

我想将我的webview的html内容转换为PDF。为此,我尝试拍摄webview内容的屏幕截图,然后使用itext将其转换为PDF。结果PDF不太清晰。

我的代码:

protected void takeimg() { 
    Picture picture = mWebView.capturePicture(); 
    Bitmap b = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), 
      Bitmap.Config.ARGB_8888); 
    Canvas c = new Canvas(b); 
    picture.draw(c); 

    // byte[] bt = b.getNinePatchChunk(); 

    // Bitmap b; 
    // View v1 = mWebView.getRootView(); 
    // v1.setDrawingCacheEnabled(true); 
    // b = Bitmap.createBitmap(v1.getDrawingCache()); 
    // v1.setDrawingCacheEnabled(false); 

    FileOutputStream fos = null; 
    try { 
     File root = new File(Environment.getExternalStorageDirectory(), 
       "Sample"); 

     if (!root.exists()) { 
      root.mkdir(); 
     } 
     String sdcardhtmlpath = root.getPath().toString() + "/" 
       + "temp_1.png"; 

     fos = new FileOutputStream(sdcardhtmlpath); 
     // fos = openFileOutput("samsp_1.jpg", MODE_WORLD_WRITEABLE); 
     if (fos != null) { 
      b.compress(Bitmap.CompressFormat.PNG, 100, fos); 

      // fos.write(bt); 
      fos.close(); 
     } 
    } catch (Exception e) { 
     Log.e("takeimg", e.toString()); 
     e.printStackTrace(); 

    } 
} 


protected void pdfimg() { 
    Document mydoc = new Document(PageSize.A3); 
    try { 
     File root = new File(Environment.getExternalStorageDirectory(), 
       "Sample"); 

     if (!root.exists()) { 
      root.mkdir(); 
     } 
     String sdcardhtmlpath = root.getPath().toString() + "/"; 
     mydoc.setMargins(0, 0, 0, 0); 
     PdfWriter.getInstance(mydoc, new FileOutputStream(sdcardhtmlpath 
       + PDFfilename)); 
     mydoc.open(); 
     Image image1 = Image.getInstance(sdcardhtmlpath + "temp_1.jpg"); 
     image1.scalePercent(95f); 

     mydoc.add(image1); 
     // mydoc.newPage(); 

     mydoc.close(); 
    } catch (Exception e) { 
     Log.e("pdi name", e.toString()); 
    } 
} 
+3

真的很好的问题.. – prakash

+1

为什么你想要截图..有各种库可用,它提供了在Android上创建的PDF文件。只需从webview中获取HTML页面的内容并使用任何lib创建PDF。这个屏幕截图技术会产生更多的新问题,然后解决你的问题。 – mudit

+0

我尝试了很多,我找不到一个完美的方式将HTML转换为PDF。如果您对此有任何想法,请解释我。 – Sniper

回答

11

更新:请参见编辑3回答运算的原题

有两种选择:

  1. 使用图书馆的HTML转换为PDF。这是迄今为止最好的选择,因为它可能(可能)将文本保存为向量。

  2. 获取HTML的高分辨率渲染,并将其保存为PNG(不是PDF格式!)。

对于HTML到PDF,wkhtmltopdf看起来像一个不错的选择,但是它依赖于Qt的,你不能在Android上真正使用。还有一些其他的库,但我怀疑他们很好地做PDF渲染。

为了得到高清晰度的WebView,你可以尝试创建自己的WebView并呼吁onMeasure(...)onLayout(...),并通过适当的参数,这样的观点是非常大的。然后调用onDraw(myOwnCanvas),webview将自己绘制到您的画布上,可以使用Canvas.setBitmap()作为Bitmap的支持。

你也许可以使用的东西的状态复制到新WebView

screenshotterWebview.onRestoreInstanceState(mWebView.onSaveInstanceState()); 

Orrr它甚至有可能使用相同的WebView,只是暂时调整其大小要大,onDraw()它你的画布,并将其重新调整大小。尽管这很棘手!

如果过大,可能会遇到内存问题。

编辑1

我想第三个,到底-什么,你想选择的,但它是一种硬派的。您可以创建自定义Canvas,写入PDF。其实几乎是容易,因为底层Canvas是Skia,它实际上包含了一个PDF后端。不幸的是,您无法在Android上访问它,所以您基本上必须在Android上创建自己的副本(有说明),并重复/覆盖所有的方法,以指向您的Skia而不是Android。请注意,有一种诱人的Picture.writeToStream()方法可以序列化Skia数据,但不幸的是,这种格式不是向前或向后兼容的,所以如果您使用它,您的代码可能只适用于几个Android版本。

我会更新如果/当我有完整的工作代码。

编辑2

其实这是不可能让自己的 “拦截” Canvas。我开始这样做,并且经历了所有函数调用序列化的单调乏味的过程。有些你不能做,因为它们是隐藏的,但那些看起来并不重要。但最后,我来到序列化Path只发现它是只写的。这对我来说似乎是一个杀手,所以唯一的选择是解释Picture.writeToStream()的结果。幸运的是,这种格式只有两种版本在使用,而且几乎相同。

编辑3 - 非常简单的方法来获得一个视图

确定的高分辨率Bitmap,原来刚开视图(可以是整个应用程序)的高分辨率位图是微不足道的。以下是如何获得双倍分辨率。显然,所有的位图看起来有点废话,但文字是在全分辨率渲染:

View window = activity.getWindow().getDecorView() 

Canvas bitmapCanvas = new Canvas(); 
Bitmap bitmap = Bitmap.createBitmap(window.getWidth()*2, window.getHeight()*2, Bitmap.Config.ARGB_8888); 

bitmapCanvas.setBitmap(bitmap); 
bitmapCanvas.scale(2.0f, 2.0f); 
window.draw(bitmapCanvas); 

bitmap.compress(Bitmap.CompressFormat.PNG, 0, myOutputStream); 

就像一个魅力。我现在放弃了获取带有矢量文本的PDF屏幕截图。这当然是可能的,但非常困难。相反,我正在努力获得一个高分辨率的PSD,其中每个绘制操作是一个单独的图层,这应该更容易。

编辑4

吁这是有点长,但成功!我已经生成了一个.xcf(GIMP)和PDF,其中每个图层都是不同的画布绘制操作。它不像我期待的那么细致,但仍然非常有用!

其实我的代码只是输出全尺寸的PNG,我在GIMP中使用“Open as layers ...”和“Autocrop layer”来制作这些文件,但是当然如果你喜欢,你可以在代码中做到这一点。我想我会把它变成一篇博文。

下载GIMPPhotoshop演示文件(以3x分辨率呈现)。

+0

对于编辑3:为什么上传0%质量的bitmap? 猜测它应该更像: 'bitmap.compress(Bitmap.CompressFormat.PNG,100,myOutputStream);' – Rappel

+0

[质量是PNG忽略](http://developer.android.com/reference/android/graphics /Bitmap.html#compress%28android.graphics.Bitmap.CompressFormat,%20int,%20java.io.OutputStream%29) – Timmmm

3

屏幕快照是什么,但你的设备显示的画面通常取决于你的手机绝对的像素,如果你的手机是480x800的屏幕快照将是相同的,普遍适用于所有的情况。

3

当然,使用此:

Bitmap bitmap; 
View v1 = MyView.getRootView(); 
v1.setDrawingCacheEnabled(true); 
bitmap = Bitmap.createBitmap(v1.getDrawingCache()); 
v1.setDrawingCacheEnabled(false); 

这里MyView的是你需要的截图观。

+2

这不是高分辨率。 – Timmmm

4

当你捕捉视图,只是屏幕绑定将捕获(由于控制权重和android渲染管道)。

捕获截图转换为PDF是棘手的方式。我认为两种方式是更合理的解决方案。

解决方案#1

写解析器(很简单),以视图内容转换(即HTML)来iText的格式。
你可以参考这篇文章获取更多信息。
http://www.vogella.com/articles/JavaPDF/article.html

也写一个解析器,你可以使用正则表达式,并提供像parseTableparseImage你自己的方法,...

解决方案#2上网所需

提供一个网址(或webservice)使用PHP或C#将HTML转换为PDF,这些库有很多不错的库。接下来,您可以将下载链接发送到客户端(Android设备)。

因此,您还可以动态地从服务器端添加一些标签,横幅...到PDF。