有什么办法可以得到高分辨率 Activity 中某个 View 的屏幕截图。
我想将我的 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());
}
}
最佳答案
更新:关于 op 的原始问题 的答案,请参见编辑 3。
有两种选择:
对于 HTML 到 PDF,wkhtmltopdf看起来是个不错的选择,但它依赖于您无法在 Android 上真正使用的 Qt。还有其他一些库,但我怀疑它们是否能很好地渲染 PDF。
要获得高分辨率的网页 View ,您可以尝试创建自己的
WebView
并调用 onMeasure(...)
和 onLayout(...)
并传递适当的参数,使 View 非常大。然后调用onDraw(myOwnCanvas)
并且 webview 将自己绘制到您的 Canvas 上,可以由 Bitmap
支持使用 Canvas.setBitmap()
.您可能可以将状态复制到新的
WebView
使用类似的东西screenshotterWebview.onRestoreInstanceState(mWebView.onSaveInstanceState());
或者甚至可以使用相同的
WebView
, 只是暂时将其调整为大,onDraw()
它到你的 Canvas ,并再次调整它的大小。但这变得非常hacky!如果你把它做得太大,你可能会遇到内存问题。
编辑 1
我想到了第三种,正是你想要的选择,但它有点硬核。您可以创建自定义
Canvas
,写入 PDF。事实上,这几乎很容易,因为底层 Canvas
是 Skia,它实际上包括一个 PDF 后端。不幸的是,您无法在 Android 上访问它,因此您基本上必须在 Android 上构建自己的副本(有说明),并复制/覆盖所有 Canvas
指向您的 Skia 而不是 Androids 的方法。注意有一个诱人的Picture.writeToStream()
序列化 Skia 数据的方法,但不幸的是,这种格式不向前或向后兼容,因此如果您使用它,您的代码可能仅适用于少数版本的 Android。如果/当我有完整的工作代码时,我会更新。
编辑 2
其实自己做“拦截”是不可能的
Canvas
.我开始这样做并经历了序列化所有函数调用的繁琐过程。有些你不能做,因为它们是隐藏的,但那些看起来并不重要。但最后我开始序列化 Path
才发现它是只写的。这对我来说似乎是一个杀手,所以唯一的选择是解释 Picture.writeToStream()
的结果。 .幸运的是,该格式只有两个版本在使用,而且几乎完全相同。编辑 3 - 获得高分辨率的真正简单方法
Bitmap
观点的好的,事实证明只是获得 View 的高分辨率位图(可以是整个应用程序)是微不足道的。这是获得双分辨率的方法。显然所有的位图看起来都有点垃圾,但文本以全分辨率呈现:
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,其中每一层都是不同的 Canvas 绘制操作。它不像我预期的那么细粒度,但仍然非常有用!实际上,我的代码只输出全尺寸的 PNG,我在 GIMP 中使用“作为图层打开...”和“自动裁剪图层”来制作这些文件,但当然,如果您愿意,您可以在代码中执行此操作。我想我会把它变成一篇博客文章。
下载GIMP或 Photoshop演示文件(以 3 倍分辨率渲染)。
关于android - Android中的高分辨率屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13468020/