android - Android中的高分辨率屏幕截图

标签 android screenshot

有什么办法可以得到高分辨率 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。这是迄今为止最好的选择,因为它将(可能)将文本保存为向量。
  • 获取 HTML 的高分辨率渲染并将其保存为 PNG(当然不是 PDF!)。

  • 对于 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 中使用“作为图层打开...”和“自动裁剪图层”来制作这些文件,但当然,如果您愿意,您可以在代码中执行此操作。我想我会把它变成一篇博客文章。

    下载GIMPPhotoshop演示文件(以 3 倍分辨率渲染)。

    关于android - Android中的高分辨率屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13468020/

    相关文章:

    android - 在 Android 上构建 RTSP 客户端的最佳方式

    ios - UIGraphicsBeginImageContext 不返回视网膜图像

    android - 是否可以在不显示 View 的情况下拍摄 View 的屏幕截图?

    java - IntelliJ IDEA 中的 JUnit 测试问题 - 找不到类

    安卓服务 : What happen at the end of Activity life?

    android - 房间实体和领域模型,它们应该分开吗?

    opencv - 从屏幕截图检测在浏览器中播放的视频——OpenCV

    android - 单击时小部件不启动服务

    javascript - 为 Protractor 设置 Screenshot Reporter

    javascript - 关于在 Phonegap Build 上将 HTML 渲染为图像或将屏幕截图渲染为图像有什么想法吗?