Android使用C++截屏并显示

时间:2023-12-21 12:09:20

  使用android底层自带的截屏源码进行修改后,将截取屏幕的内容再次显示在屏幕上,使屏幕呈现出暂停的效果。

  android自带的截屏代码在android\JB\frameworks\base\cmds\screencap\screencap.cpp文件中,我是参考这个进行修改的,代码如下:

  

 int main(int argc, char** argv)
{ sp<ProcessState> proc(ProcessState::self());
// create a client to surfaceflinger
sp<SurfaceComposerClient> client = new SurfaceComposerClient(); //创建SurfaceFlinger的本地代理
char str[];
DisplayInfo display;
//获取屏幕的宽高等信息
client->getDisplayInfo(client->getBuiltInDisplay(HWC_DISPLAY_PRIMARY), &display); //创建SurfaceControl的本地代理
sp<SurfaceControl> surfaceControl = client->createSurface(String8("testsurface"),
/**/, /**/, PIXEL_FORMAT_RGBA_8888, ); /*********************************************************************/
SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(); //设置z轴
surfaceControl->setSize(display.w, display.h);
surfaceControl->setPosition(, ); //起始位置
SurfaceComposerClient::closeGlobalTransaction();
// 获取Surface本地代理
sp<Surface> surface = surfaceControl->getSurface();//获取surface
Surface::SurfaceInfo info; //创建SurfaceControl的本地代理
sp<SurfaceControl> surfaceControl1 = client->createSurface(String8("wenfu"),
display.w, display.h, PIXEL_FORMAT_RGBA_8888, );
SurfaceComposerClient::openGlobalTransaction();
surfaceControl1->setLayer(); //设置z轴
surfaceControl1->setSize(display.w, display.h);
surfaceControl1->setPosition(, ); //起始位置
SurfaceComposerClient::closeGlobalTransaction();
// 获取Surface本地代理
sp<Surface> surface1 = surfaceControl1->getSurface();//获取surface
Surface::SurfaceInfo info1; ssize_t bpr ;
SkBitmap bitmap;
SkCanvas canvas ;
SkCanvas canvas1;
SkBitmap bitmap1;
SkPath path;
SkPaint paint; //paint可以指定绘图的颜色,文本的大小及对齐方式,编码格式 int sx,sy;
int w,h;
int flg = ;
int flg2 = ;
int lastx = , lasty = , ctrx = , ctry = ;
char st[];
/////////////////////////////////////////////////////////////////////////////////////////
void const* mapbase = MAP_FAILED;
ssize_t mapsize = -;
void const* base = ;
size_t size = ;
int ww,hh;
ScreenshotClient screenshot; //下面是截屏操作
sp<IBinder> display1 = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
if (display1 != NULL && screenshot.update(display1) == NO_ERROR)
{
base = screenshot.getPixels();
ww = screenshot.getWidth();
hh = screenshot.getHeight();
size = screenshot.getSize();
} if (base) //以下是显示部分
{
SkBitmap bitm;
bitm.setConfig(SkBitmap::kARGB_8888_Config, ww, hh);
bitm.setPixels((void*)base);
surface1->lock(&info1);
bpr = info1.s * bytesPerPixel(info1.format);
bitmap1.setConfig(SkBitmap::kARGB_8888_Config, display.w, display.h, bpr);
bitmap1.setPixels(info1.bits);
canvas1.setDevice(new SkDevice(bitmap1));
canvas1.drawBitmap(bitm, SkIntToScalar(), SkIntToScalar()); //从0,0点开始画图
surface1->unlockAndPost();
}
if (mapbase != MAP_FAILED) {
munmap((void *)mapbase, mapsize);
}
//////////////////////////////////////////////////////////////////////////////////////// while(); return ;
}

  代码写的比较粗糙,实验型代码。最开始使用自带的screencap来做,比较耗时,自带的是将截取的屏幕内容保存到png文件里,让后我再读取png文件,这样截屏存储又显示速度很慢,需要5到6秒的时间,这样直接截屏显示只需要不到500ms时间。