`

Android camera 默认显示黑白的问题

阅读更多
转自:http://tassardge.blog.163.com/blog/static/172301708201123043753616/

在初次接触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。
----AlbertChen
分享到:
评论

相关推荐

    NDK调用OpenGL使用Camera2进行相机黑白滤镜预览(FBO离屏渲染)

    5. **显示结果**:完成滤镜处理后,将FBO的内容读回,绑定默认的帧缓冲,将处理后的图像绘制到屏幕上。 6. **处理帧率和同步**:为了保持流畅的预览,需要管理好渲染帧率和相机帧率的同步,避免过度渲染或丢帧。 7...

    android数字图像处理源码

    Android Camera API允许开发者在捕获图像前进行一系列操作,如调整亮度、对比度或应用实时滤镜。预处理通常涉及从相机硬件接收的原始数据(如YUV格式)转换为更易处理的格式(如RGB)。这需要理解不同颜色空间的工作...

    zxing实现二维码扫描

    - 兼容性问题:对于旧版Android系统,可能需要处理一些兼容性问题,例如API级别的差异。 8. **进一步优化**: - 白名单与黑名单:设置允许扫描的URL类型,防止恶意链接。 - 自定义扫描框:可以绘制自定义的扫描...

    二维码,条形码的生成与扫描

    <uses-permission android:name="android.permission.CAMERA" /> ``` 2. 创建一个Activity继承自`CaptureActivity`,这个类是ZXing提供的扫描界面。 3. 如果不想使用默认的扫描界面,可以自定义布局,并通过`...

    二维码扫描和生成源代码 QRZXing二维码.rar

    <uses-permission android:name="android.permission.CAMERA" /> ``` 通过以上介绍,我们可以看出QRZXing库在二维码扫描和生成方面具有强大的功能。对于Android开发者来说,它是一个不可或缺的工具,能轻松地将...

    html5-qrcode:跨平台HTML5 QR码阅读器

    支持从文件或智能手机上的默认相机扫描代码。 最近添加的内容支持各种格式的条形码扫描。 支持两种API Html5QrcodeScanner具有UI的端到端扫描器,集成少于十行代码。 Html5Qrcode功能强大的API集,可用于构建UI...

    扫一扫源码

    3. 实时扫描:为了实现连续扫描,应用通常会利用手机硬件加速,如GPU,以及硬件级别的图像处理API,如Android的Camera2 API或iOS的AVFoundation框架,实现实时预览和扫描。 三、用户体验优化 1. 对焦与亮度调整:...

    BarcodeScanningApp:扫描一本书的条形码

    <uses-permission android:name="android.permission.CAMERA" /> ``` **三、创建扫描活动** 1. **创建新类**:创建一个名为`ScanActivity`的新Activity,继承自`AppCompatActivity`。 2. **集成ZXing扫描器**:...

Global site tag (gtag.js) - Google Analytics