3

我想以编程方式截取屏幕截图。我已经从这个http://www.pocketmagic.net/?p=1473参加了以下课程 ,但它没有截图。当我尝试使用调试代码时调试代码

 __android_log_print(ANDROID_LOG_DEBUG,DEBUG_TAG,"messsage");

它无法识别 ANDROID_LOG_DEBUG 给我这个符号“ANDROID_LOG_DEBUG”的错误无法解决,而是我包含了 android/log.h

请帮助解决这个问题。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <time.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <jni.h>
#include "pixelflinger.h"
#include<sys/syscall.h>
#include<sys/stat.h>
#include <string.h>
#include <android/log.h>

typedef struct {
     long filesize;
     char reserved[2];
     long headersize;
     long infoSize;
     long width;
     long depth;
     short biPlanes;
     short bits;
     long biCompression;
     long biSizeImage;
     long biXPelsPerMeter;
     long biYPelsPerMeter;
     long biClrUsed;
     long biClrImportant;
} BMPHEAD;

//copyright text
char cprght[255]="Copyright(C)2009 Motisan Radu , All rights reserved.\n radu.motisan@gmail.com";
//surface pointer
static GGLSurface gr_framebuffer[2];
//handler
static int gr_fb_fd = -1;
//v screen info
static struct fb_var_screeninfo vi;
//f screen info
struct fb_fix_screeninfo fi;

static void dumpinfo(struct fb_fix_screeninfo *fi,
                     struct fb_var_screeninfo *vi);

static int get_framebuffer(GGLSurface *fb)
{
    int fd;
    void *bits;

    fd = open("/dev/graphics/fb0", O_RDWR);
    if(fd < 0) {
        perror("cannot open fb0");
        return -1;
    }

    if(ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
        perror("failed to get fb0 info");
        return -1;
    }

    if(ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
        perror("failed to get fb0 info");
        return -1;
    }

    //dumpinfo(&fi, &vi);

    bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(bits == MAP_FAILED) {
        perror("failed to mmap framebuffer");
        return -1;
    }

    fb->version = sizeof(*fb);
    fb->width = vi.xres;
    fb->height = vi.yres;
    fb->stride = fi.line_length / (vi.bits_per_pixel >> 3);
    fb->data = bits;
    fb->format = GGL_PIXEL_FORMAT_RGB_565;

    fb++;

    fb->version = sizeof(*fb);
    fb->width = vi.xres;
    fb->height = vi.yres;
    fb->stride = fi.line_length / (vi.bits_per_pixel >> 3);
    fb->data = (void*) (((unsigned) bits) + vi.yres * vi.xres * 2);
    fb->format = GGL_PIXEL_FORMAT_RGB_565;

    return fd;
}


static void dumpinfo(struct fb_fix_screeninfo *fi, struct fb_var_screeninfo *vi)
{
    /*fprintf(stderr,"vi.xres = %d\n", vi->xres);
    fprintf(stderr,"vi.yres = %d\n", vi->yres);
    fprintf(stderr,"vi.xresv = %d\n", vi->xres_virtual);
    fprintf(stderr,"vi.yresv = %d\n", vi->yres_virtual);
    fprintf(stderr,"vi.xoff = %d\n", vi->xoffset);
    fprintf(stderr,"vi.yoff = %d\n", vi->yoffset);
    fprintf(stderr, "vi.bits_per_pixel = %d\n", vi->bits_per_pixel);

    fprintf(stderr, "fi.line_length = %d\n", fi->line_length);*/

}


//int main(int argc, char **argv)
jint Java_com_example_JazzkActivity_stringFromJNI( JNIEnv* env, jobject thiz )
//int main(int argc, char **argv)
{

  __android_log_print(ANDROID_LOG_DEBUG,DEBUG_TAG,"messsage");
 //get screen capture
  gr_fb_fd = get_framebuffer(gr_framebuffer);
  if (gr_fb_fd <= 0) exit(1);
  //__android_log_print(ANDROID_API_LEVEL_H);
  int w = vi.xres, h = vi.yres, depth = vi.bits_per_pixel;

  //convert pixel data
  uint8_t *rgb24;
  if (depth == 16)
  {
    rgb24 = (uint8_t *)malloc(w * h * 3);
    int i = 0;
    for (;i<w*h;i++)
    {
        uint16_t pixel16 = ((uint16_t *)gr_framebuffer[0].data)[i];
        // RRRRRGGGGGGBBBBBB -> RRRRRRRRGGGGGGGGBBBBBBBB
        // in rgb24 color max is 2^8 per channel (*255/32 *255/64 *255/32)
        rgb24[3*i+2]   = (255*(pixel16 & 0x001F))/ 32;      //Blue
        rgb24[3*i+1]   = (255*((pixel16 & 0x07E0) >> 5))/64;    //Green
        rgb24[3*i]     = (255*((pixel16 & 0xF800) >> 11))/32;   //Red
    }
  }
  else
  if (depth == 24) //exactly what we need
  {
    rgb24 = (uint8_t *) gr_framebuffer[0].data;
  }
  else
  if (depth == 32) //skip transparency channel
  {
      rgb24 = (uint8_t *) malloc(w * h * 3);
      //rgb24 = new uint8_t[w * h * 3];
    int i=0;
    for (;i<w*h;i++)
    {
        uint32_t pixel32 = ((uint32_t *)gr_framebuffer[0].data)[i];
        // in rgb24 color max is 2^8 per channel
        rgb24[3*i+0]   =  pixel32 & 0x000000FF;         //Blue
        rgb24[3*i+1]   = (pixel32 & 0x0000FF00) >> 8;   //Green
        rgb24[3*i+2]   = (pixel32 & 0x00FF0000) >> 16;  //Red
    }
  }
  else
  {
    //free
        close(gr_fb_fd);
    exit(2);
  };
  //save RGB 24 Bitmap
  int bytes_per_pixel = 3;
  BMPHEAD bh;
  memset ((char *)&bh,0,sizeof(BMPHEAD)); // sets everything to 0
  //bh.filesize  =   calculated size of your file (see below)
  //bh.reserved  = two zero bytes
  bh.headersize  = 54L;         // for 24 bit images
  bh.infoSize  =  0x28L;        // for 24 bit images
  bh.width     = w;         // width of image in pixels
  bh.depth     = h;         // height of image in pixels
  bh.biPlanes  =  1;            // for 24 bit images
  bh.bits      = 8 * bytes_per_pixel;   // for 24 bit images
  bh.biCompression = 0L;        // no compression
  int bytesPerLine;
  bytesPerLine = w * bytes_per_pixel;   // for 24 bit images
  //round up to a dword boundary
  if (bytesPerLine & 0x0003)
  {
        bytesPerLine |= 0x0003;
        ++bytesPerLine;
  }
  bh.filesize = bh.headersize + (long)bytesPerLine * bh.depth;
  FILE * bmpfile;
  //printf("Bytes per line : %d\n", bytesPerLine);
  bmpfile = fopen("screen.bmp", "wb");
  if (bmpfile == NULL)
  {
    close(gr_fb_fd);
    //exit(3);
  }
  fwrite("BM",1,2,bmpfile);
  fwrite((char *)&bh, 1, sizeof (bh), bmpfile);
  //fwrite(rgb24,1,w*h*3,bmpfile);
  char *linebuf;
  linebuf = (char *) calloc(1, bytesPerLine);
  if (linebuf == NULL)
  {
        fclose(bmpfile);
    close(gr_fb_fd);
    exit(4);
  }
  int line,x;
  for (line = h-1; line >= 0; line --)
  {
        // fill line linebuf with the image data for that line
    for( x =0 ; x < w; x++ )
    {
        *(linebuf+x*bytes_per_pixel) = *(rgb24 + (x+line*w)*bytes_per_pixel+2);
        *(linebuf+x*bytes_per_pixel+1) = *(rgb24 + (x+line*w)*bytes_per_pixel+1);
        *(linebuf+x*bytes_per_pixel+2) = *(rgb24 + (x+line*w)*bytes_per_pixel+0);
    }
    // remember that the order is BGR and if width is not a multiple
        // of 4 then the last few bytes may be unused
    fwrite(linebuf, 1, bytesPerLine, bmpfile);
  }
  fclose(bmpfile);
  close(gr_fb_fd);
  return 0;
}

安卓.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS    := -llog
LOCAL_MODULE    := jazzk
### Add all source file names to be included in lib separated by a whitespace
LOCAL_SRC_FILES := capturescr.c

include $(BUILD_SHARED_LIBRARY)

提前致谢

如果有人知道以编程方式实现屏幕截图的其他方式,请发布。

4

2 回答 2

0

我已经构建了您的代码,并且在调用 jni 时效果很好。我只是删除 __android_log_print(ANDROID_LOG_DEBUG,DEBUG_TAG,"messsage")标签,并在 Android 源代码项目中构建。

您只需要将 .so 文件放入您的 Java 项目。我不尝试构建 NDK。

于 2012-08-03T06:34:59.240 回答
0

在最新的 ADT(22.6.2 捆绑包,包含 Eclipse 4.3.1)、NDK(r9d)中也有同样的问题。通过擦除整个问题,安装 ADT( 2013 年 9 月 4 日,2013 年 9 月 31 日的22.0.5包,其中包含 Eclipse 4.2.1),NDK(r9b)来解决。

于 2014-04-03T00:21:21.883 回答