这里写自定义目录标题
前情提要
在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