Android P 縮短screencap時間

前情提要

在Android P 系統上使用screencap截一張圖片需要3s,爲了加快截圖時間,決定修改screencap保存的圖片格式

方法:修改screencap保存的圖片格式爲JPEG

screencap源碼路徑:/frameworks/base/cmds/screencap/screencap.cpp
源碼中screencap只能保存成png格式 或者在stdout中打印出來


int main(int argc, char** argv)
{
    ...
    // 保存成png格式
    if (png) {
        const SkImageInfo info =
            SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType, dataSpaceToColorSpace(d));
        SkPixmap pixmap(info, base, s * bytesPerPixel(f));
        struct FDWStream final : public SkWStream {
          size_t fBytesWritten = 0;
          int fFd;
          FDWStream(int f) : fFd(f) {}
          size_t bytesWritten() const override { return fBytesWritten; }
          bool write(const void* buffer, size_t size) override {
            fBytesWritten += size;
            return size == 0 || ::write(fFd, buffer, size) > 0;
          }
        } fdStream(fd);
        (void)SkEncodeImage(&fdStream, pixmap, SkEncodedImageFormat::kPNG, 100);
        if (fn != NULL) {
            notifyMediaScanner(fn);
        }
    } else { // 在stdout打印出來
        uint32_t c = dataSpaceToInt(d);
        write(fd, &w, 4);
        write(fd, &h, 4);
        write(fd, &f, 4);
        write(fd, &c, 4);
        size_t Bpp = bytesPerPixel(f);
        for (size_t y=0 ; y<h ; y++) {
            write(fd, base, w*Bpp);
            base = (void *)((char *)base + s*Bpp);
        }
    }
    close(fd);
    if (mapbase != MAP_FAILED) {
        munmap((void *)mapbase, mapsize);
    }

    // b/36066697: Avoid running static destructors.
    _exit(0);
  }

增加圖片保存格式爲JPEG


int main(int argc, char** argv)
{
    
    const char* pname = argv[0];
    bool png = false;
    bool jpg = false; // 增加JPG格式
    int32_t displayId = DEFAULT_DISPLAY_ID;
    int c;
    while ((c = getopt(argc, argv, "pjhd:")) != -1) {
        switch (c) {
            case 'p':
                png = true;
                break;
            case 'j':
                jpg = true;
                break;
            case 'd':
                displayId = atoi(optarg);
                break;
            case '?':
            case 'h':
                usage(pname);
                return 1;
        }
    }
   ...
    // 保存成png格式
    if (png) {
    ... 
     } else if(jpg) { // 增加JPEG格式
        const SkImageInfo info =
             SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType, dataSpaceToColorSpace(d));
         SkPixmap pixmap(info, base, s * bytesPerPixel(f));
         struct FDWStream final : public SkWStream {
           size_t fBytesWritten = 0;
           int fFd;
           FDWStream(int f) : fFd(f) {}
           size_t bytesWritten() const override { return fBytesWritten; }
           bool write(const void* buffer, size_t size) override {
             fBytesWritten += size;
             return size == 0 || ::write(fFd, buffer, size) > 0;
           }
         } fdStream(fd);
         // 和上面png代碼基本相同,不同點就在SkEncodedImageFormat::kJPEG
         (void)SkEncodeImage(&fdStream, pixmap, SkEncodedImageFormat::kJPEG, 100);
         if (fn != NULL) {
             notifyMediaScanner(fn);
         }
     }
  • 編譯: make screencap -j4
  • 拷貝編譯出來的out/target/product/XXX/system/bin/screencap到設備的system/bin/screencap
  • 使用: $adb shell screencap -j sdcard/screen.jpg

解析

screencap 使用skia庫來繪圖
官網地址: https://skia.org/user/api/SkPixmap_Reference

其他方法

降低設備分辨率和像素密度可以加速截圖

具體步驟:
查看設備分辨率
$ adb shell wm size
修改設備分辨率
$ adb shell wm size 1920dpx1080dp
重置分辨率
$ adb shell wm size reset

查看到像素密度是160

$ adb shell wm density
Physical density: 160

如果分辨率相應縮小1倍後,像素密度應該同樣縮小一倍,爲80

$ adb shell wm density 80
# wm -h
Window manager (window) commands:
  help
      Print this help text.
  size [reset|WxH|WdpxHdp]
    Return or override display size.
    width and height in pixels unless suffixed with 'dp'.
  density [reset|DENSITY]
    Return or override display density.
  overscan [reset|LEFT,TOP,RIGHT,BOTTOM]
    Set overscan area for display.
  scaling [off|auto]
    Set display scaling mode.
  dismiss-keyguard
    Dismiss the keyguard, prompting user for auth if necessary.
  tracing (start | stop)
    Start or stop window tracing.

也可以把屬性寫死在/system/build.prop

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章