Skip to content

Instantly share code, notes, and snippets.

@amitn
Created March 20, 2014 06:25
Show Gist options
  • Save amitn/9658326 to your computer and use it in GitHub Desktop.
Save amitn/9658326 to your computer and use it in GitHub Desktop.
Android screen shot using OpenCV

Introduction

Capturing Android screen buffer and transferring it to OpenCV.

This application will create a screen shoot from the Android screen buffer using OpenCV.

There are better ways to do it, but now you can process the screen image using OpenCV.

You will need the Android SDK, Android NDK, OpenCV and root on the device.

I'm asuming that the Android screen buffer is in RGBA8888 format. You can find out the screen buffer format using:

vscreeninfo.bits_per_pixel

vscreeninfo.red.offset
vscreeninfo.green.offset
vscreeninfo.blue.offset
vscreeninfo.transp.offset

vscreeninfo.red.length
vscreeninfo.green.length
vscreeninfo.blue.length
vscreeninfo.transp.length

Files

README.md
jni/cv_screenshot.cpp
jni/Android.mk
jni/Application.mk

Build

$ ndk-build

Push to device

  1. Mount the system as rw:
$ adb shell "mount -o remount,rw /system"
  1. Push:
$ adb push libs/armeabi-v7a/cv_screenshot /system/bin/cv_screenshot

Run

$ adb shell
# cd /sdcard
# cv_screenshot
# exit
$ adb pull /sdcard/screen.png
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# OpenCV
OPENCV_CAMERA_MODULES := off
OPENCV_INSTALL_MODULES := off
OPENCV_LIB_TYPE := STATIC
include $(OPENCV_SDK_PATH)/sdk/native/jni/OpenCV.mk
# App
LOCAL_CPP_EXTENSION := .cc .cpp .cxx
LOCAL_MODULE := cv_screenshot
LOCAL_SRC_FILES := cv_screenshot.cpp
include $(BUILD_EXECUTABLE)
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-8
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <opencv2/opencv.hpp>
int main()
{
struct fb_var_screeninfo vscreeninfo;
struct fb_fix_screeninfo fscreeninfo;
void *data;
int bytespp;
int offset;
cv::Mat imgbuf;
int fbfd = open("/dev/graphics/fb0", O_RDWR);
if (fbfd < 0)
goto out;
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vscreeninfo) < 0)
goto out;
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscreeninfo) < 0)
goto out;
data = mmap(0, fscreeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
imgbuf = cv::Mat(cv::Size(vscreeninfo.xres, vscreeninfo.yres),
CV_8UC4, data, fscreeninfo.line_length);
cv::cvtColor(imgbuf, imgbuf, CV_RGBA2BGR);
cv::imwrite("screen.png", imgbuf);
out:
close(fbfd);
}
@cethap
Copy link

cethap commented Feb 11, 2016

Hi, I was trying to test this code for android but the screenshot is a black image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment