Android用C++创建surface显示RGB数据

转自:http://blog.csdn.net/tung214/article/details/36628897

以下在Android 4.4平台开发测试,用于在屏幕直接显示RGB数据,当然,如果要直接显示YUV,写个函数转换一下也能直接显示。

其中从文件中获取RGB的RGB数据可以从这里下载 http://kc.cc/WeVp

[cpp]  view plain copy
  1. #include <cutils/memory.h>  
  2.   
  3. #include <unistd.h>  
  4. #include <utils/Log.h>  
  5.   
  6. #include <binder/IPCThreadState.h>  
  7. #include <binder/ProcessState.h>  
  8. #include <binder/IServiceManager.h>  
  9.   
  10. #include <gui/Surface.h>  
  11. #include <gui/SurfaceComposerClient.h>  
  12. #include <gui/ISurfaceComposer.h>  
  13. #include <ui/DisplayInfo.h>  
  14. #include <ui/Rect.h>  
  15. #include <ui/Region.h>  
  16. #include <android/native_window.h>  
  17. #include <SkGraphics.h>  
  18. #include <SkBitmap.h>  
  19. #include <SkCanvas.h>  
  20. #include <SkDevice.h>  
  21. #include <SkStream.h>  
  22. #include <SkImageDecoder.h>  
  23.   
  24. #include <hardware/hwcomposer_defs.h>  
  25. using namespace android;  
  26.   
  27. static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {  
  28.     /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then 
  29.         we can map to SkBitmap::kARGB_8888_Config, and optionally call 
  30.         bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator) 
  31.     */  
  32.     switch (format) {  
  33.     case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;  
  34.     case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;  
  35.     case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;  
  36.     default:                        return SkBitmap::kNo_Config;  
  37.     }  
  38. }  
  39.   
  40. int main(int argc, char** argv)  
  41. {  
  42.     // set up the thread-pool  
  43.     sp<ProcessState> proc(ProcessState::self());  
  44.     ProcessState::self()->startThreadPool();  
  45.   
  46.     // create a client to surfaceflinger  
  47.     sp<SurfaceComposerClient> client = new SurfaceComposerClient();  
  48.     //DisplayoutBuffer display;  
  49.     //client->getDisplayoutBuffer(client->getBuiltInDisplay(HWC_DISPLAY_PRIMARY), &display);  
  50.     sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(  
  51.             ISurfaceComposer::eDisplayIdMain));  
  52.     DisplayInfo dinfo;  
  53.     //获取屏幕的宽高等信息  
  54.     status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);  
  55.     printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n",   
  56.         dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);  
  57.     if (status)  
  58.         return -1;  
  59.     sp<SurfaceControl> surfaceControl = client->createSurface(String8("testsurface"),  
  60.             dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565, 0);  
  61.   
  62. /****************************第一张图******************************************************/  
  63.     SurfaceComposerClient::openGlobalTransaction();  
  64.     surfaceControl->setLayer(100000);//设定Z坐标  
  65.     surfaceControl->setPosition(0, 0);//以左上角为(0,0)设定显示位置  
  66.     SurfaceComposerClient::closeGlobalTransaction();  
  67.     surfaceControl->show();//感觉没有这步,图片也能显示  
  68.     sp<Surface> surface = surfaceControl->getSurface();  
  69.   
  70.     ANativeWindow_Buffer outBuffer;  
  71.     //Surface::SurfaceoutBuffer outBuffer;  
  72.     surface->lock(&outBuffer,NULL);//获取surface缓冲区的地址  
  73.     ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);  
  74.     android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);//往surface缓冲区塞要显示的RGB内容  
  75.     surface->unlockAndPost();  
  76.     sleep(3);  
  77.   
  78. //从文件中获取RGB数据显示 下载地址:http://kc.cc/WeVp  
  79. /****************************第二张图******************************************************/  
  80.     SurfaceComposerClient::openGlobalTransaction();  
  81.     surfaceControl->setSize(480, 272);  
  82.     surfaceControl->setPosition(100, 100);  
  83.     SurfaceComposerClient::closeGlobalTransaction();  
  84.     surfaceControl->show();//感觉没有这步,图片也能显示  
  85.       
  86.     FILE *fp = fopen("/tmp/rgb565.rgb","rb");//我们从一个文件里获取RGB565图像数据 480*272  
  87.     if(fp != NULL){  
  88.         unsigned char *rgb565Data = new unsigned char[480*272*2];  
  89.         memset(rgb565Data,0x00,480*272*2);  
  90.         fread(rgb565Data,1,480*272*2,fp);  
  91.         surface->lock(&outBuffer,NULL);  
  92.         //bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);  
  93.         //android_memset16((uint16_t*)outBuffer.bits, 0x04E0, bpr*outBuffer.height);  
  94.         memcpy(outBuffer.bits,rgb565Data,480*272*2);  
  95.         delete[] rgb565Data;  
  96.         surface->unlockAndPost();  
  97.     }  
  98.     fclose(fp);  
  99.     sleep(3);  
  100.   
  101. //用skia画图  
  102. /*******************************第三张图***************************************************/  
  103.     SurfaceComposerClient::openGlobalTransaction();  
  104.     surfaceControl->setSize(320, 420);  
  105.     surfaceControl->setPosition(100, 100);  
  106.     SurfaceComposerClient::closeGlobalTransaction();  
  107.     surfaceControl->show();//感觉没有这部图片也能显示  
  108.       
  109.     SkPaint paint;  
  110.     paint.setColor(SK_ColorBLUE);  
  111.     Rect rect(0, 0, 320, 240);  
  112.     Region dirtyRegion(rect);  
  113.       
  114.     surface->lock(&outBuffer, &rect);  
  115.     bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);  
  116. //    printf("w=%d,h=%d,bpr=%d,fmt=%d,bits=%p\n", outBuffer.w, outBuffer.h, bpr, outBuffer.format, outBuffer.bits);  
  117.     SkBitmap bitmap;  
  118.     bitmap.setConfig(convertPixelFormat(outBuffer.format), 320, 240, bpr);  
  119.     bitmap.setPixels(outBuffer.bits);  
  120.     SkCanvas canvas;  
  121.     SkRegion clipReg;  
  122.     const Rect b(dirtyRegion.getBounds());  
  123.     clipReg.setRect(b.left, b.top, b.right, b.bottom);  
  124.     canvas.clipRegion(clipReg);  
  125.     canvas.drawARGB(0, 0xFF, 0x00, 0xFF);  
  126.     canvas.drawCircle(200, 200, 100, paint);  
  127.     bitmap.notifyPixelsChanged();  
  128.     surface->unlockAndPost();  
  129.     sleep(3);  
  130.    
  131.   
  132. /**********************************************************************************/  
  133.     SkFILEStream stream("/sdcard/test.jpg");  
  134.     SkImageDecoder* codec = SkImageDecoder::Factory(&stream);  
  135.     if(codec){  
  136.         SkBitmap bmp;  
  137.         stream.rewind();  
  138.         codec->decode(&stream, &bmp, SkBitmap::kRGB_565_Config, SkImageDecoder::kDecodePixels_Mode);  
  139.         surface->lock(&outBuffer,NULL);  
  140.         bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);  
  141.         bitmap.setConfig(convertPixelFormat(outBuffer.format), 320, 240, bpr);  
  142.         bitmap.setPixels(outBuffer.bits);  
  143.         //dev = new SkDevice(bitmap);  
  144.         //canvas.setDevice(dev);  
  145.         canvas.drawBitmap(bmp, SkIntToScalar(200), SkIntToScalar(300));  
  146.         surface->unlockAndPost();  
  147.         sleep(3);  
  148.         //delete dev;  
  149.     }  
  150.       
  151.     IPCThreadState::self()->joinThreadPool();  
  152.       
  153.     IPCThreadState::self()->stopProcess();  
  154.   
  155.     return 0;  
  156. }  

Android.mk

[plain]  view plain copy
  1. LOCAL_PATH:= $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3.   
  4. LOCAL_SRC_FILES:= \  
  5.     testsurface.cpp  
  6.   
  7. LOCAL_C_INCLUDES := \  
  8.     external/skia/include/core  
  9.   
  10. LOCAL_SHARED_LIBRARIES := \  
  11.     libcutils \  
  12.     libutils \  
  13.     libbinder \  
  14.     libui \  
  15.     libgui \  
  16.     libskia  
  17.   
  18. LOCAL_MODULE:= testsurface  
  19.   
  20. LOCAL_MODULE_TAGS := tests  
  21.   
  22. include $(BUILD_EXECUTABLE)  

代码修改自http://blog.csdn.net/lxl123/article/details/21465841 他的代码在Android4.4编译会报错.

你可能感兴趣的:(Android用C++创建surface显示RGB数据)