Android中的高分辨率屏幕截图

时间:2012-11-20 06:55:18

标签: android screenshot

有没有办法在活动中获得某个视图的高分辨率屏幕截图。

我想将我的网页浏览的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());
    }
}

4 个答案:

答案 0 :(得分:11)

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

有两种选择:

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

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

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

    要获得高分辨率的网页浏览量,您可以尝试创建自己的WebView并调用onMeasure(...)onLayout(...)并传递相应的参数,以便视图非常大。然后调用onDraw(myOwnCanvas),webview将自己绘制到您的画布上,该画布可以使用BitmapCanvas.setBitmap()支持。

    您可以使用类似

    之类的内容将状态复制到新的WebView
    screenshotterWebview.onRestoreInstanceState(mWebView.onSaveInstanceState());
    

    Orrr甚至可以使用相同的WebView,只是暂时将其大小调整为onDraw()到画布,然后再将其调整大小。但这变得非常hacky!

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

    编辑1

    我想到了第三个,正是你想要的选项,但它是一种硬核。您可以创建一个写入PDF的自定义Canvas。事实上,几乎很容易,因为底层Canvas是Skia,实际上包含PDF后端。很遗憾,您无法在Android上访问它,因此您基本上必须在Android上构建自己的副本(有说明),并复制/覆盖所有Canvas方法以指向您的Skia而不是Androids。请注意,有一个诱人的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

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

    实际上我的代码只输出全尺寸PNG,我在GIMP中使用“Open as layers ...”和“Autocrop layer”来制作这些文件,当然如果你愿意,你可以在代码中这样做。我想我会把它变成博客文章。

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

答案 1 :(得分:4)

当您捕获视图时,只会捕获屏幕(由于控制权重和Android渲染管道)。

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

解决方案#1

编写一个解析器(很简单)将webview内容(即HTML)转换为iText格式。
有关更多信息,请参阅此文章 http://www.vogella.com/articles/JavaPDF/article.html

另外,为了编写解析器,您可以使用REGEX并提供自己的方法,如parseTableparseImage,...

解决方案#2 需要互联网

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:3)

当然,请使用此:

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

此处MyView是您需要截图的视图。