Android Screen Capture Codes Sample

  1. /*
  2.  * Copyright (C) 2010 The Android Open Source Project
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. #include
  17. #include
  18. #include
  19. #include
  20. #include
  21. #include
  22. #include
  23. #include
  24. #include
  25. #include
  26. #include
  27. #include
  28. #include
  29. #include
  30. #include
  31. using namespace android;
  32. static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
  33. static void usage(const char* pname)
  34. {
  35.     fprintf(stderr,
  36.             "usage: %s [-hp] [-d display-id] [FILENAME]\n"
  37.             "   -h: this message\n"
  38.             "   -p: save the file as a png.\n"
  39.             "   -d: specify the display id to capture, default %d.\n"
  40.             "If FILENAME ends with .png it will be saved as a png.\n"
  41.             "If FILENAME is not given, the results will be printed to stdout.\n",
  42.             pname, DEFAULT_DISPLAY_ID
  43.     );
  44. }
  45. static SkBitmap::Config flinger2skia(PixelFormat f)
  46. {
  47.     switch (f) {
  48.         case PIXEL_FORMAT_A_8:
  49.             return SkBitmap::kA8_Config;
  50.         case PIXEL_FORMAT_RGB_565:
  51.             return SkBitmap::kRGB_565_Config;
  52.         case PIXEL_FORMAT_RGBA_4444:
  53.             return SkBitmap::kARGB_4444_Config;
  54.         default:
  55.             return SkBitmap::kARGB_8888_Config;
  56.     }
  57. }
  58. static status_t vinfoToPixelFormat(const fb_var_screeninfo& vinfo,
  59.         uint32_t* bytespp, uint32_t* f)
  60. {
  61.     switch (vinfo.bits_per_pixel) {
  62.         case 16:
  63.             *f = PIXEL_FORMAT_RGB_565;
  64.             *bytespp = 2;
  65.             break;
  66.         case 24:
  67.             *f = PIXEL_FORMAT_RGB_888;
  68.             *bytespp = 3;
  69.             break;
  70.         case 32:
  71.             // TODO: do better decoding of vinfo here
  72.             *f = PIXEL_FORMAT_RGBX_8888;
  73.             *bytespp = 4;
  74.             break;
  75.         default:
  76.             return BAD_VALUE;
  77.     }
  78.     return NO_ERROR;
  79. }
  80. int main(int argc, char** argv)
  81. {
  82.     ProcessState::self()->startThreadPool();
  83.     const char* pname = argv[0];
  84.     bool png = false;
  85.     int32_t displayId = DEFAULT_DISPLAY_ID;
  86.     int c;
  87.     while ((c = getopt(argc, argv, "phd:")) != -1) {
  88.         switch (c) {
  89.             case 'p':
  90.                 png = true;
  91.                 break;
  92.             case 'd':
  93.                 displayId = atoi(optarg);
  94.                 break;
  95.             case '?':
  96.             case 'h':
  97.                 usage(pname);
  98.                 return 1;
  99.         }
  100.     }
  101.     argc -= optind;
  102.     argv += optind;
  103.     int fd = -1;
  104.     if (argc == 0) {
  105.         fd = dup(STDOUT_FILENO);
  106.     } else if (argc == 1) {
  107.         const char* fn = argv[0];
  108.         fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
  109.         if (fd == -1) {
  110.             fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
  111.             return 1;
  112.         }
  113.         const int len = strlen(fn);
  114.         if (len >= 4 && 0 == strcmp(fn+len-4, ".png")) {
  115.             png = true;
  116.         }
  117.     }
  118.    
  119.     if (fd == -1) {
  120.         usage(pname);
  121.         return 1;
  122.     }
  123.     void const* mapbase = MAP_FAILED;
  124.     ssize_t mapsize = -1;
  125.     void const* base = 0;
  126.     uint32_t w, s, h, f;
  127.     size_t size = 0;
  128.     ScreenshotClient screenshot;
  129.     sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
  130.     if (display != NULL && screenshot.update(display) == NO_ERROR) {
  131.         base = screenshot.getPixels();
  132.         w = screenshot.getWidth();
  133.         h = screenshot.getHeight();
  134.         s = screenshot.getStride();
  135.         f = screenshot.getFormat();
  136.         size = screenshot.getSize();
  137.     } else {
  138.         const char* fbpath = "/dev/graphics/fb0";
  139.         int fb = open(fbpath, O_RDONLY);
  140.         if (fb >= 0) {
  141.             struct fb_var_screeninfo vinfo;
  142.             if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) == 0) {
  143.                 uint32_t bytespp;
  144.                 if (vinfoToPixelFormat(vinfo, &bytespp, &f) == NO_ERROR) {
  145.                     size_t offset = (vinfo.xoffset + vinfo.yoffset*vinfo.xres) * bytespp;
  146.                     w = vinfo.xres;
  147.                     h = vinfo.yres;
  148.                     s = vinfo.xres;
  149.                     size = w*h*bytespp;
  150.                     mapsize = offset + size;
  151.                     mapbase = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, fb, 0);
  152.                     if (mapbase != MAP_FAILED) {
  153.                         base = (void const *)((char const *)mapbase + offset);
  154.                     }
  155.                 }
  156.             }
  157.             close(fb);
  158.         }
  159.     }
  160.     if (base) {
  161.         if (png) {
  162.             SkBitmap b;
  163.             b.setConfig(flinger2skia(f), w, h, s*bytesPerPixel(f));
  164.             b.setPixels((void*)base);
  165.             SkDynamicMemoryWStream stream;
  166.             SkImageEncoder::EncodeStream(&stream, b,
  167.                     SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
  168.             SkData* streamData = stream.copyToData();
  169.             write(fd, streamData->data(), streamData->size());
  170.             streamData->unref();
  171.         } else {
  172.             write(fd, &w, 4);
  173.             write(fd, &h, 4);
  174.             write(fd, &f, 4);
  175.             size_t Bpp = bytesPerPixel(f);
  176.             for (size_t y=0 ; y<h ; y++) {
  177.                 write(fd, base, w*Bpp);
  178.                 base = (void *)((char *)base + s*Bpp);
  179.             }
  180.         }
  181.     }
  182.     close(fd);
  183.     if (mapbase != MAP_FAILED) {
  184.         munmap((void *)mapbase, mapsize);
  185.     }
  186.     return 0;
  187. }

이 블로그의 인기 게시물

install php in os x

둘 중 누군가 그녀를 죽였다, 범인 해설

unity plugin