转自:http://blog.csdn.net/tung214/article/details/36628897
以下在Android 4.4平台开发测试,用于在屏幕直接显示RGB数据,当然,如果要直接显示YUV,写个函数转换一下也能直接显示。
其中从文件中获取RGB的RGB数据可以从这里下载 http://kc.cc/WeVp
- #include <cutils/memory.h>
- #include <unistd.h>
- #include <utils/Log.h>
- #include <binder/IPCThreadState.h>
- #include <binder/ProcessState.h>
- #include <binder/IServiceManager.h>
- #include <gui/Surface.h>
- #include <gui/SurfaceComposerClient.h>
- #include <gui/ISurfaceComposer.h>
- #include <ui/DisplayInfo.h>
- #include <ui/Rect.h>
- #include <ui/Region.h>
- #include <android/native_window.h>
- #include <SkGraphics.h>
- #include <SkBitmap.h>
- #include <SkCanvas.h>
- #include <SkDevice.h>
- #include <SkStream.h>
- #include <SkImageDecoder.h>
- #include <hardware/hwcomposer_defs.h>
- using namespace android;
- static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
- /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
- we can map to SkBitmap::kARGB_8888_Config, and optionally call
- bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
- */
- switch (format) {
- case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
- case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
- case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
- default: return SkBitmap::kNo_Config;
- }
- }
- int main(int argc, char** argv)
- {
- // set up the thread-pool
- sp<ProcessState> proc(ProcessState::self());
- ProcessState::self()->startThreadPool();
- // create a client to surfaceflinger
- sp<SurfaceComposerClient> client = new SurfaceComposerClient();
- //DisplayoutBuffer display;
- //client->getDisplayoutBuffer(client->getBuiltInDisplay(HWC_DISPLAY_PRIMARY), &display);
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
- DisplayInfo dinfo;
- //获取屏幕的宽高等信息
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
- printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n",
- dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);
- if (status)
- return -1;
- sp<SurfaceControl> surfaceControl = client->createSurface(String8("testsurface"),
- dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565, 0);
- /****************************第一张图******************************************************/
- SurfaceComposerClient::openGlobalTransaction();
- surfaceControl->setLayer(100000);//设定Z坐标
- surfaceControl->setPosition(0, 0);//以左上角为(0,0)设定显示位置
- SurfaceComposerClient::closeGlobalTransaction();
- surfaceControl->show();//感觉没有这步,图片也能显示
- sp<Surface> surface = surfaceControl->getSurface();
- ANativeWindow_Buffer outBuffer;
- //Surface::SurfaceoutBuffer outBuffer;
- surface->lock(&outBuffer,NULL);//获取surface缓冲区的地址
- ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
- android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);//往surface缓冲区塞要显示的RGB内容
- surface->unlockAndPost();
- sleep(3);
- //从文件中获取RGB数据显示 下载地址:http://kc.cc/WeVp
- /****************************第二张图******************************************************/
- SurfaceComposerClient::openGlobalTransaction();
- surfaceControl->setSize(480, 272);
- surfaceControl->setPosition(100, 100);
- SurfaceComposerClient::closeGlobalTransaction();
- surfaceControl->show();//感觉没有这步,图片也能显示
- FILE *fp = fopen("/tmp/rgb565.rgb","rb");//我们从一个文件里获取RGB565图像数据 480*272
- if(fp != NULL){
- unsigned char *rgb565Data = new unsigned char[480*272*2];
- memset(rgb565Data,0x00,480*272*2);
- fread(rgb565Data,1,480*272*2,fp);
- surface->lock(&outBuffer,NULL);
- //bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
- //android_memset16((uint16_t*)outBuffer.bits, 0x04E0, bpr*outBuffer.height);
- memcpy(outBuffer.bits,rgb565Data,480*272*2);
- delete[] rgb565Data;
- surface->unlockAndPost();
- }
- fclose(fp);
- sleep(3);
- //用skia画图
- /*******************************第三张图***************************************************/
- SurfaceComposerClient::openGlobalTransaction();
- surfaceControl->setSize(320, 420);
- surfaceControl->setPosition(100, 100);
- SurfaceComposerClient::closeGlobalTransaction();
- surfaceControl->show();//感觉没有这部图片也能显示
- SkPaint paint;
- paint.setColor(SK_ColorBLUE);
- Rect rect(0, 0, 320, 240);
- Region dirtyRegion(rect);
- surface->lock(&outBuffer, &rect);
- bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
- // printf("w=%d,h=%d,bpr=%d,fmt=%d,bits=%p\n", outBuffer.w, outBuffer.h, bpr, outBuffer.format, outBuffer.bits);
- SkBitmap bitmap;
- bitmap.setConfig(convertPixelFormat(outBuffer.format), 320, 240, bpr);
- bitmap.setPixels(outBuffer.bits);
- SkCanvas canvas;
- SkRegion clipReg;
- const Rect b(dirtyRegion.getBounds());
- clipReg.setRect(b.left, b.top, b.right, b.bottom);
- canvas.clipRegion(clipReg);
- canvas.drawARGB(0, 0xFF, 0x00, 0xFF);
- canvas.drawCircle(200, 200, 100, paint);
- bitmap.notifyPixelsChanged();
- surface->unlockAndPost();
- sleep(3);
- /**********************************************************************************/
- SkFILEStream stream("/sdcard/test.jpg");
- SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
- if(codec){
- SkBitmap bmp;
- stream.rewind();
- codec->decode(&stream, &bmp, SkBitmap::kRGB_565_Config, SkImageDecoder::kDecodePixels_Mode);
- surface->lock(&outBuffer,NULL);
- bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
- bitmap.setConfig(convertPixelFormat(outBuffer.format), 320, 240, bpr);
- bitmap.setPixels(outBuffer.bits);
- //dev = new SkDevice(bitmap);
- //canvas.setDevice(dev);
- canvas.drawBitmap(bmp, SkIntToScalar(200), SkIntToScalar(300));
- surface->unlockAndPost();
- sleep(3);
- //delete dev;
- }
- IPCThreadState::self()->joinThreadPool();
- IPCThreadState::self()->stopProcess();
- return 0;
- }
Android.mk
- LOCAL_PATH:= $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= \
- testsurface.cpp
- LOCAL_C_INCLUDES := \
- external/skia/include/core
- LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libbinder \
- libui \
- libgui \
- libskia
- LOCAL_MODULE:= testsurface
- LOCAL_MODULE_TAGS := tests
- include $(BUILD_EXECUTABLE)
代码修改自http://blog.csdn.net/lxl123/article/details/21465841 他的代码在Android4.4编译会报错.