Android camera 默认显示黑白的问题

在初次接触 android 的时候就注意到通过模拟器,相机预览的时候只能显示黑白电影。这些天总算有点空闲时间了,决定研究下这个。 关于 android camera 的构造不再说了,模拟器上使用用的是一个虚拟的 Camera-----FakeCamera 这个大家应该都知道。

首先初略的了解一下 camera preview 图像显示的原理。 Camera application 初始化的时候会创建一个 surfaceview ,从 camera device 接收到的数据就可以通过它显示在屏幕上。内部处理的流程是很复杂的,下面我只给出一个从初始化到绘图函数调用的流程。

Surface 初始化:

Android_view_surface:: Surface_init--> SurfaceComposerClient::CreateSurface-->

SurfaceFlinger:: createSurface--> Android_view_surface:: setSurface

 

 

Camera 数据缓冲区 Heap 初始化:

CameraHardwareStub::initHeapLocked--> new MemoryBase--> new FakeCamera

 

 

Heap 缓冲区注册到 surface:

Android_hardware_camera:: android_hardware_Camera_setPreviewDisplay-->

Camera:: setPreviewDisplay--> CameraService::Client::setPreviewDisplay-->

CameraService::Client::registerPreviewBuffers--> LayerBuffer::registerBuffers

 

 

FakeCamera 原始数据的传递与绘图:

CameraHardwareStub::previewThread--> CameraService::Client::previewCallback-->

CameraService::Client::postPreviewFrame--> ISurface:: postBuffer-->

LayerBuffer::postBuffer--> LayerBuffer::BufferSource::postBuffer-->

LayerBase::invalidate--> SurfaceFlinger::signalEvent--> SurfaceFlinger::threadLoop-->

SurfaceFlinger::handleRepaint--> LayerBase::draw-->

LayerBuffer::BufferSource::onDraw--> LayerBase::drawWithOpenGL

 

FakeCamera 得到数据为 Yuv422, 原以为是库里某个地方绘图的时候出问题,但 LayerBuffer::OnDraw 往下走很复杂的:

                       t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
                // just show the Y plane of YUV buffers。 不明白为什么google这么做。。。。。

但要解决预览为黑白电影的问题应该就比较简单了。只要我们将 YUV 数据转换为 RGB 丢给 cameraService 就可以了。用以下的代码替代 ccrgb16toyuv_wo_colorkey

int32_t ccrgb16toyuv_wo_colorkey (uint8_t *rgb16,uint8_t *yuv422,uint32_t *param,uint8_t *table[])

{

       int32_t width_dst = param[0];

    int32_t height_dst = param[1];

       memcpy(yuv422, rgb16, width_dst*height_dst*2);

}

CameraService 中改动:

status_t CameraService::Client::registerPreviewBuffers ()

{

   。。。。。。。。。。。。。。。。。。。。。。。

    ISurface::BufferHeap buffers(w, h, w, h,

                                PIXEL_FORMAT_RGB_565 ,

//PIXEL_FORMAT_YCbCr_420_SP,

                                 transform,

                                 0,

                                 mHardware->getPreviewHeap());

 

   status_t ret = mSurface->registerBuffers(buffers);

    if (ret != NO_ERROR) {

        LOGE("registerBuffers failed with status %d", ret);

    }

    return ret;

}

PIXEL_FORMAT_RGB_565 替换 PIXEL_FORMAT_YCbCr_420_SP 。这样就可以了。不妨动手试一试吧,看看是不是预览视频变为彩色的了。

对于实际的 camera device 出来的数据如果是 yuv 的话,也可以通过算法将 yuv 转换为 RGB ,这样做并不会导致转换效率降低,因为即使将 yuv 得数据丢到 surfaceflinger 中,最终还是会转换为 BMp

要在Android平台上开发一个高效的二维码扫描识别系统,你需要掌握图像处理、解码算法以及Android开发的相关技术。推荐的资料《Android毕设:高效二维码扫描识别系统》详细描述了这一过程。 参考资源链接:[Android毕设:高效二维码扫描识别系统](https://wenku.youkuaiyun.com/doc/504778nt5f?spm=1055.2569.3001.10343) 首先,二维码的扫描识别过程可以分为几个关键步骤:图像捕获、图像预处理、二维码定位、图像二值化和二维码解码。图像捕获通常通过AndroidCamera API实现。为了提高识别效率,需要在捕获到图像后进行预处理,包括调整大小、旋转、滤波去噪等,以适应不同的扫描环境和条件。 接着,二维码定位是通过寻找图像中的特定模式来实现的,例如QR Code具有特定的定位图案。这个步骤是至关重要的,因为二维码的解码依赖于定位图案来确定图像的坐标系。 图像二值化处理是将捕获的图像转换为黑白两色,这是为了减少后续处理的数据量,同时也使得二维码的模块更容易被识别。二值化后的图像可以通过不同的算法来识别二维码,如ZBar、ZXing等。 二维码解码则需要算法来解析这些模块,解码过程通常包括错误检测和纠正。解码算法能够从二值化后的图像中提取二维码的原始数据,并将其转换为可读的信息,如网址、电话号码等。 智能处理是应用开发中的另一个重要方面。根据解码出的信息类型,应用可以执行相应的动作,例如:如果解析出的是网址,应用将调用默认浏览器打开;如果是电话号码,则触发拨打电话功能;如果是短信内容,则弹出发送短信的界面。 在实现过程中,开发者可以使用Android SDK提供的Camera API进行图像捕获,使用ZXing库进行二维码的解码,使用Intent系统来实现电话拨打和网页浏览等功能。同时,还需要考虑用户体验,比如快速响应用户的操作,提供流畅的动画效果等。 总的来说,开发一个高效的二维码扫描识别应用需要对图像处理和解码算法有深入的理解,并且在Android开发方面具备实际操作能力。通过学习《Android毕设:高效二维码扫描识别系统》,你将获得这一过程的具体实现细节和关键技术的应用,这将对你的项目开发提供极大的帮助。 参考资源链接:[Android毕设:高效二维码扫描识别系统](https://wenku.youkuaiyun.com/doc/504778nt5f?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值