Android jpegライブラリを使用したスクリーンショット


jtest.c
#include <string.h>  
#include <stdlib.h>
//#include <jni.h>  

#include <math.h>  
#include <stdio.h>  
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

typedef uint8_t BYTE;  
#define true 1  
#define false 0  


#include "jpeglib.h"

#define FB_DEVICE "/dev/graphics/fb0"
static int g_fd;

typedef struct{
	int x;
	int y;
}point;

typedef struct
{
	int w;    /* width */
	int h;    /* high */
	int bpp;  /* bits per pixel */
	unsigned char *fbmem;
}screen;

int init_fb(screen *fb)
{
	if ((g_fd = open(FB_DEVICE, O_RDWR)) < 0){ 
		fprintf(stderr, "Open %s failed:%s
", FB_DEVICE, strerror(errno)); return -1; } struct fb_var_screeninfo fb_var; struct fb_fix_screeninfo fb_fix; if (ioctl(g_fd, FBIOGET_VSCREENINFO, &fb_var) < 0){ fprintf(stderr, "fb ioctl failed:%s
", strerror(errno)); return -1; } if (ioctl(g_fd, FBIOGET_FSCREENINFO, &fb_fix) < 0){ fprintf(stderr, "fb ioctl failed:%s
", strerror(errno)); return -1; } fb->w = fb_fix.line_length / 4; fb->h = fb_var.yres; fb->bpp = fb_var.bits_per_pixel; printf("--->^_^ %d, %d, %d, %d
", fb_var.xres_virtual, fb_var.yres_virtual, fb_var.xoffset, fb_var.yoffset); printf("--->^_^ %d
", fb_fix.line_length); #if 1 printf("width:%d\thign:%d\tbpp:%d
", fb->w, fb->h, fb->bpp); #endif fb->fbmem = mmap(0, fb->w * fb->h * fb->bpp /8, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0); if (fb->fbmem == MAP_FAILED){ fprintf(stderr, "fb mmap failed:%s
", strerror(errno)); return -1; } close(g_fd); return 0; } int term_fb(screen *fb) { munmap(fb->fbmem, fb->w * fb->h * fb->bpp / 8); return 0; } int generateJPEG(BYTE* data,int w, int h, const char* outfilename) { int nComponent = 3; struct jpeg_compress_struct jcs; struct jpeg_error_mgr jem; jcs.err = jpeg_std_error(&jem); jpeg_create_compress(&jcs); FILE* f=fopen(outfilename,"wb"); if (f==NULL) { free(data); return 0; } jpeg_stdio_dest(&jcs, f); jcs.image_width = w; jcs.image_height = h; jcs.input_components = nComponent; if (nComponent==1) jcs.in_color_space = JCS_GRAYSCALE; else jcs.in_color_space = JCS_RGB; jpeg_set_defaults(&jcs); jpeg_set_quality (&jcs, 60, true); jpeg_start_compress(&jcs, TRUE); JSAMPROW row_pointer[1]; int row_stride; row_stride = jcs.image_width*nComponent; while (jcs.next_scanline < jcs.image_height) { row_pointer[0] = & data[jcs.next_scanline*row_stride]; jpeg_write_scanlines(&jcs, row_pointer, 1); } jpeg_finish_compress(&jcs); jpeg_destroy_compress(&jcs); fclose(f); return 1; } BYTE* generateRGB24Data() { struct { BYTE r; BYTE g; BYTE b; } pRGB[100][199]; memset( pRGB, 0, sizeof(pRGB) ); int i=0, j=0; for( i=50;i<70;i++ ){ for( j=70;j<140;j++ ){ pRGB[i][j].b = 0xff; } } for( i=0;i<10;i++ ){ for( j=0;j<199;j++ ){ pRGB[i][j].r = 0xff; } } BYTE* ret = (BYTE*)malloc(sizeof(BYTE)*100*199*3); memcpy(ret, (BYTE*)pRGB, sizeof(pRGB)); return ret; } int main(void) { int i, j; unsigned char *p; int w, h; //BYTE* data = generateRGB24Data(); screen fb_screen; init_fb(&fb_screen); w = fb_screen.w; h = fb_screen.h; p = (unsigned char *)malloc(w * h * 3); printf("0x%x %x %x %x
", *fb_screen.fbmem, *(fb_screen.fbmem + 1), \ *(fb_screen.fbmem + 2), *(fb_screen.fbmem + 3)); for(i = 0; i < h; i++){ for(j = 0; j < w; j++){ *(p + (i * w + j) * 3) = *(fb_screen.fbmem + (i * w + j) * 4 + 0); *(p + (i * w + j) * 3 + 1) = *(fb_screen.fbmem + (i * w + j) * 4 + 1); *(p + (i * w + j) * 3 + 2) = *(fb_screen.fbmem + (i * w + j) * 4 + 2); } } generateJPEG(p, fb_screen.w, fb_screen.h, "/sdcard/test.jpg"); term_fb(&fb_screen); free(p); //free(data); return 0; }

Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= jtest.c

LOCAL_MODULE:= jtest

#LOCAL_FORCE_STATIC_EXECUTABLE := true

#LOCAL_STATIC_LIBRARIES := libc 
LOCAL_SHARED_LIBRARIES:= libjpeg libc
LOCAL_C_INCLUDES := $(LOCAL_PATH)

LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := debug

include $(BUILD_EXECUTABLE)

実行後/sdcard/ディレクトリでtest.jpgを生産