android 直接在屏幕上绘图
android 的application 都是有窗口系统的,会把各种事件给阻拦掉.但是,用c++写的程序是直接在linux上运行的,并没有窗口这一概念,所以可以向鼠标一样,只绘制图像而不响应任何窗口时间.
具体实现是通过SurfaceComposerClient,这个类相当于surfaceflinger的代理,可以创建一个显示图像的surface.
注意,不同系统的接口可能不一样.若有问题,可以参考一下本系统中frameworks/base/service/input/SpriteController.cpp中的doUpdateSprites()函数.这个函数是显示鼠标的最主核心的函数.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<SkImageDecoder.h> 2 #include <utils/RefBase.h> 3 #include <utils/Looper.h> 4 #include <gui/SurfaceComposerClient.h> 5 #include <gui/Surface.h> 6 #include <SkBitmap.h> 7 #include <SkCanvas.h> 8 #include <SkColor.h> 9 #include <SkPaint.h> 10 #include <SkXfermode.h> 11 #include <android/native_window.h> 12 #include <unistd.h> 13 #include <cutils/log.h> 14 #include <ui/DisplayInfo.h> 15 16 #define LOG_TAG "zhy" 17 18 using namespace android; 19 int main() 20 { 21 SkBitmap bitmap; 22 SkImageDecoder::DecodeFile("/system/data/test.png", &bitmap); 23 sp<SurfaceComposerClient> pSurfaceComposerClient = new SurfaceComposerClient(); 24 int32_t width = bitmap.height(); 25 int32_t height = bitmap.width(); 26 ALOGI("width= %d \n", width); 27 ALOGI("height= %d \n", height); 28 sp<SurfaceControl> surfaceControl = pSurfaceComposerClient->createSurface( 29 String8("test"), width, height, PIXEL_FORMAT_RGBA_8888, 30 ISurfaceComposerClient::eHidden); 31 32 if (surfaceControl == NULL || !surfaceControl->isValid()) { 33 ALOGE("Error creating sprite surface."); 34 return -1; 35 } 36 sp<Surface> surface = surfaceControl->getSurface(); 37 ANativeWindow_Buffer outBuffer; 38 status_t status = surface->lock(&outBuffer, NULL); 39 if (status) { 40 ALOGE("Error %d locking sprite surface before drawing.", status); 41 } else { 42 SkBitmap surfaceBitmap; 43 ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format); 44 surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config, 45 outBuffer.width, outBuffer.height, bpr); 46 surfaceBitmap.setPixels(outBuffer.bits); 47 SkCanvas surfaceCanvas(surfaceBitmap); 48 SkPaint paint; 49 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 50 surfaceCanvas.drawBitmap(bitmap, 0, 0, &paint); 51 if (outBuffer.width > uint32_t(bitmap.width())) { 52 paint.setColor(0); // transparent fill color 53 surfaceCanvas.drawRectCoords(bitmap.width(), 0, 54 outBuffer.width, bitmap.height(), paint); 55 } 56 if (outBuffer.height > uint32_t(bitmap.height())) { 57 paint.setColor(0); // transparent fill color 58 surfaceCanvas.drawRectCoords(0, bitmap.height(), 59 outBuffer.width, outBuffer.height, paint); 60 } 61 status = surface->unlockAndPost(); 62 if (status) { 63 ALOGE("Error %d unlocking and posting sprite surface after drawing.", status); 64 } 65 } 66 67 int x = 0, y = 0; 68 SurfaceComposerClient::openGlobalTransaction(); 69 //surfaceControl->setAlpha(1.0f); 70 surfaceControl->setLayer(100000); 71 //surfaceControl->setMatrix(1.0, 1.0, 1.0, 1.0); 72 SurfaceComposerClient::closeGlobalTransaction(); 73 while(true){ 74 ALOGI("openGlobalTransaction \n"); 75 SurfaceComposerClient::openGlobalTransaction(); 76 surfaceControl->setPosition(x, y); 77 x = (x+10) %1920; 78 y = (y+10) %1280; 79 static bool isShow = false; 80 if(!isShow){ 81 surfaceControl->show(); 82 isShow = true; 83 } 84 ALOGI("closeGlobalTransaction \n"); 85 SurfaceComposerClient::closeGlobalTransaction(); 86 sleep(1); 87 88 } 89 return 0; 90 }