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

Solutions Collecting From Web of "Android中的高分辨率屏幕截图"

更新:请参阅编辑3以获取op的原始问题的答案

有两个选项:

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

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

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

为了获得高分辨率的webview,你可以尝试创build自己的WebView并调用onMeasure(...)onLayout(...)并传递适当的参数,以便视图非常大。 然后调用onDraw(myOwnCanvas) ,webview将自己绘制到您的canvas上,可以使用Canvas.setBitmap()来支持Bitmap

您可以使用类似的方法将状态复制到新的WebView

 screenshotterWebview.onRestoreInstanceState(mWebView.onSaveInstanceState()); 

Orrr甚至可以使用相同的WebView ,只是临时调整它的大小, onDraw()它的canvas,并再次resize。 虽然这很棘手!

如果你做得太大,你可能会遇到内存问题。

编辑1

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

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

编辑2

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

编辑3 – 真正简单的方法来获得高分辨率视图的Bitmap

好吧,事实certificate,获取视图的高分辨率位图(可以是整个应用程序)是微不足道的。 这里是如何获得双倍分辨率。 显然,所有的位图看起来有点废话,但文本呈现在全分辨率:

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

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

编辑4

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

其实我的代码只是输出全尺寸的PNG,我用GIMP中的“Open as layers …”和“Autocrop layer”来制作这些文件,当然如果你愿意的话,你也可以用代码来做到这一点。 我想我会把它变成一个博客文章。

下载GIMP或Photoshop演示文件(以3x分辨率渲染)。

当你捕捉视图时,只要屏幕绑定就会捕获(由于控制权重和android渲染pipe道)。

捕获截图转换为PDF是棘手的方式。 我认为两种方式是比较合理的解决办法。

解决scheme#1

编写一个parsing器(很简单)将webview内容(即HTML)转换为iText格式。
你可以参考这篇文章获取更多信息。
http://www.vogella.com/articles/JavaPDF/article.html

也写一个parsing器,你可以使用REGEX,并提供自己的方法,如parseTableparseImage ,…

解决scheme2 互联网必需

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

所以你也可以dynamic地添加一些标签,横幅,…从服务器端的PDF。

屏幕截图不过是您的设备显示的图片,通常取决于您的手机的绝对像素,如果您的手机是480×800的屏幕截图将是相同的,并且通常适用于所有情况。

当然,使用这个:

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

这里MyView是你需要的截图。