如何从Android相机捕获原始图像

时间:2013-02-08 17:21:12

标签: android camera

takePicture rawCallback返回一个空指针。 getPictureFormat仅允许使用.jpg。虽然可以使用getParameters()setJpegQuality(100)setParameters改进jpeg,但返回的图像仍然是jpeg。要获取位图图像需要调用BitmapFactory.decodeByteArray,这可能需要1/2秒才能处理。

我正在处理的应用程序需要相机可以生成的最详细的图像,这并不一定意味着漂亮。原始相机芯片捕获格式是拜耳。

3 个答案:

答案 0 :(得分:10)

android(至少是我的)有2个相机参数"rawsave-mode""rawfname",默认为rawsave-mode=0。通过设置rawsave-mode=1,相机将保存原始相机图像文件,并照常执行其他相机功能。

Camera.Parameters parameters=preview.camera.getParameters();
parameters.set("rawsave-mode", "1");
parameters.set("rawfname", "/mnt/sdcard/test.raw");
preview.camera.setParameters(parameters);
preview.camera.takePicture(shutterCallback, null, jpegCallback);

生成的文件的实际名称将被修改为包含正在生成的原始文件的参数。对于我的某个机器人,生成的名称为"test__1604x1206_10_2.raw",其为a1 1604x1206图片,10bit格式为2.而"test__1284x966_10_3.raw"为1284x966图片,10 bit格式3. 10 bytes存储为2 byte short int (little endian)

parameters.set("rawsave-mode", "2");
// setting the rawsave-mode to 2 increased the resolution to 3204x2406
// and output the file test__3204x2406_10_2.raw

图像数据大致为8 bit,但浮在10 bit内,其中较亮的图像可能使用较高的值而较暗的较低。这允许图像处理软件创建直方图并捕获图像的有用范围。由于光不是常数,因此也可能需要以不同的方式调整一个通道,以使图像看起来颜色正确。网上有很多关于色彩理论的信息,可以完全解释这一点,但是新用户要注意,10 bit8的转换很快就会深入。如果你想要漂亮的图片,请使用android图片捕获而不是原始图片!

格式表示位的拜耳模式。 Bayer是一种格式,其中行和列的奇数/偶数值指示像素表示的颜色,其中RGB对于每个像素的每个颜色通道具有8 bit值,拜耳只有一个{{ 1}}像素值,其中一个像素为红色,然后是下一个绿色,红色,绿色,红色,绿色。然后下一行有蓝色,绿色,蓝色,绿色,蓝绿色。要确定像素的10 bit值,需要解释周围​​的像素。

RGB

格式3的像素顺序为

Format 2 has pixel order
//            0 1 2 3 4 5
//          0 G R G R G R
//          1 B G B G B G
//          2 G R G R G R
//          3 B G B G B G

我不确定这种技术是否适用于其他机器人,或者它是否适用于未来的机器人。如果有人试图这样做,请添加成功或失败的评论。我的手机是直接中国进口解锁iHTC Android手机已根植。

答案 1 :(得分:2)

捕获原始图像的代码:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.view.KeyEvent;
import android.app.ProgressDialog;
import android.app.Dialog;
import android.os.Handler;
import android.os.Message;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;
import android.hardware.Camera.Size;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.util.Log;

public class Camera extends Activity implements SurfaceHolder.Callback {

    private int mMode;
    private boolean mIssdcardExist = false;
    private VideoPreview mVideoPreview; //缺VideoPreview这个类
    private int mPrvW = 640, mPrvH = 480;
    private int mDispW = 640, mDispH = 480;
    private int mPicW = 2560, mPicH = 1920;
    private Camera mCamera;
    private Camera.Parameters mCameraParam;
    private int mIsPreviewing = 0;
    private volatile int mIsFocused = 0;
    private volatile int mIsCapture = 0;
    private long mFocusStartTime;
    private long mFocusCallbackTime;
    private long mCaptureStartTime;
    private long mShutterCallbackTime;
    private long mRawPictureCallbackTime;
    private long mJpegPictureCallbackTime;
    private final AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback();
    private final ShutterCallback mShutterCallback = new ShutterCallback();
    private final RawPictureCallback mRawPictureCallback = new RawPictureCallback();
    private static final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory().toString() + "/DCIM/CameraEM/";
    private int mAFEngMode = 0;

    public static final int CAPTURE_ID = Menu.FIRST;

    private String TAG = "EM-Camera";

    private final int DIALOG_PROGRESS = 1000;
    private ProgressDlgHandler mProgressDlgHandler = new ProgressDlgHandler();
    private final int EVENT_FULL_SCAN_START = 100;
    private final int EVENT_FULL_SCAN_COMPLETE = 101;
    private boolean mIsTest = false;
    private boolean mProgressDlgExists = false;

    private boolean mIsRawCapture = false;
    private String mRawCaptureFileName;

    private boolean mIsOnPause = false;
    private int mPos = 0;
    private static final int MSG_AF_MODE1_EVENT = 1001;
    private static final int MSG_AF_MODE3_EVENT = 1003;
    private static final int MSG_AF_MODE4_EVENT = 1004;
    private mAFMode1FirstThread threadFirst;
    private AFMode1Thread mode1Thread;
    private AFMode2Thread mode2Thread;
    private AFMode3Thread mode3Thread;
    private AFMode4Thread mode4Thread;
    private RawCaptureThread mRawCaptureThread;
    private boolean mCanBack = true;

    private Button mButtonPass;
    private Button mButtonFail;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera_test);

        Window win = getWindow();
        win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if(Environment.getExternalStorageState().equals(Environment.MEDIA_REMOVED))
        {
            mIssdcardExist = false;
        }
        else
        {
            File file = new File(CAMERA_IMAGE_BUCKET_NAME);
            if(!file.isDirectory())
            {
                file.mkdirs();
            }
            mIssdcardExist = true;
        }

        mButtonPass = (Button) findViewById(R.id.camera_test_pass);
        mButtonPass.setOnClickListener(mButtonHandler);

        mButtonFail = (Button) findViewById(R.id.camera_test_fail);
        mButtonFail.setOnClickListener(mButtonHandler);
    }

        @Override
    public void onResume() {
        super.onResume();
        Log.i(TAG, "onResume ");
        mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview);
        mVideoPreview.setAspectRatio(mPrvW, mPrvH);
        SurfaceHolder holder = mVideoPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mIsTest = false;
        mIsOnPause = false;
    }

        @Override
    public void onPause() {
        mIsOnPause = true;
        if(null != mode1Thread && true == mode1Thread.isAlive()){
            try{
                mode1Thread.join();
            }catch(Exception e){
            }

        }

        if(null != threadFirst && true == threadFirst.isAlive()){
            try{
                threadFirst.join();
            }catch(Exception e){
            }

        }

        if(null != mode2Thread && true == mode2Thread.isAlive()){
            try{
                mode2Thread.join();
            }catch(Exception e){
            }

        }

        if(null != mode3Thread && true == mode3Thread.isAlive()){
            try{
                mode3Thread.join();
            }catch(Exception e){
            }

        }

        if(null != mode4Thread && true == mode4Thread.isAlive()){
            try{
                mode4Thread.join();
            }catch(Exception e){
            }

        }

        if(null != mRawCaptureThread && true == mRawCaptureThread.isAlive()){
            try{
                mRawCaptureThread.join();
            }catch(Exception e){
            }

        }

        super.onPause();
        Log.i(TAG, "super onPause.");
        this.finish();
    }

        @Override
        protected Dialog onCreateDialog(int id){
            if(id == DIALOG_PROGRESS){
                ProgressDialog dialog = new ProgressDialog(this);
                dialog.setMessage("It is in full scan, please wait......");
                dialog.setCancelable(false);
                return dialog;
            }
            return null;
        }

        private class ProgressDlgHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EVENT_FULL_SCAN_START:
                    showDialog(DIALOG_PROGRESS);
                    mProgressDlgExists = true;
                    break;
                case EVENT_FULL_SCAN_COMPLETE:
                    dismissDialog(DIALOG_PROGRESS);
                    mProgressDlgExists = false;
                    break;
            }
        }
    }


    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        mDispW = w;
        mDispH = h;
        Log.i(TAG, "surfaceChanged width is : " + w);
        Log.i(TAG, "surfaceChanged height is : " + h);
        startPreview();
    }

    public void surfaceCreated(SurfaceHolder holder) {
        openCamera();
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            closeCamera();
            Log.i(TAG, "surfaceCreated closeCamera ");
        }       
    }

    public void surfaceDestroyed(SurfaceHolder arg0) {
            stopPreview();
        closeCamera();
        Log.i(TAG, "surfaceDestroyed closeCamera ");
    }

    private void openCamera() {
        if (mCamera == null) {
            mCamera = Camera.open();
            Log.i(TAG, "Enter openCamera to init the mCamera.");
            if(null == mCamera){
                Log.i(TAG, "init the mCamera is null.");
            }
        }
    }
    private void closeCamera() {
        if(null != mCamera){
            mCamera.release();
            mCamera = null;
        }
    }
    private void startPreview() {
        mCameraParam = mCamera.getParameters();
        //GW616 Camera preview problem
        // Set a preview size that is closest to the viewfinder height and has
        // the right aspect ratio.
        Size size = mCameraParam.getPictureSize();
        List<Size> sizes = mCameraParam.getSupportedPreviewSizes();
        Size optimalSize = getOptimalPreviewSize(
                sizes, (double) size.width / size.height);
        if (optimalSize != null) {
            mCameraParam.setPreviewSize(optimalSize.width, optimalSize.height);
        }
        //end
//      mCameraParam.setPreviewSize(mPrvW, mPrvH);
        mCameraParam.set("fps-mode", 0);    // Frame rate is normal
        mCameraParam.set("cam-mode", 0);    // Cam mode is preview
        mCamera.setParameters(mCameraParam);
        Log.i(TAG, "startPreview width is : " + mPrvW);
        Log.i(TAG, "startPreview height is : " + mPrvH);
        mCamera.startPreview();
        mIsPreviewing = 1;
    }
    private void stopPreview() {
        if(null != mCamera){
            mCamera.stopPreview();
        }
        mIsPreviewing = 0;
    }

    private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) {
        final double ASPECT_TOLERANCE = 0.05;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        // Because of bugs of overlay and layout, we sometimes will try to
        // layout the viewfinder in the portrait orientation and thus get the
        // wrong size of mSurfaceView. When we change the preview size, the
        // new overlay will be created before the old one closed, which causes
        // an exception. For now, just get the screen size

        Display display = getWindowManager().getDefaultDisplay();
        int targetHeight = Math.min(display.getHeight(), display.getWidth());

        if (targetHeight <= 0) {
            // We don't know the size of SurefaceView, use screen height
            WindowManager windowManager = (WindowManager)
                    getSystemService(this.WINDOW_SERVICE);
            targetHeight = windowManager.getDefaultDisplay().getHeight();
        }

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            Log.v(TAG, "No preview size match the aspect ratio");
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        Log.v(TAG, String.format(
                "Optimal preview size is %sx%s",
                optimalSize.width, optimalSize.height));
        return optimalSize;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_CAMERA:
                this.CapturePicture();
                return true;
            case KeyEvent.KEYCODE_DPAD_CENTER:
                return true;
            case KeyEvent.KEYCODE_SEARCH:
                return true;
            case KeyEvent.KEYCODE_FOCUS:
                return true;        
            }
            return super.onKeyDown(keyCode, event);
    }

    private void CapturePicture(){
        if(false == mIssdcardExist)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("sdcard not available");
            builder.setMessage("Please insert sdcard.");
            builder.setPositiveButton("OK" , null);
            builder.create().show();
            return;
         }

         if(Environment.getExternalStorageState().equals(Environment.MEDIA_SHARED))
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("sdcard is busy");
                    builder.setMessage("Sorry, your SD card is busy.");
                    builder.setPositiveButton("OK" , null);
                    builder.create().show();
                    return;
        }

        if(true == mIsTest)
        {
            Toast.makeText(this,"It is in capturing, can not repeat capture.",Toast.LENGTH_LONG).show();
            if(true == mProgressDlgExists)
            {
                showDialog(DIALOG_PROGRESS);
            }
            return;
        }

        Intent intent = getIntent();
        int TestMode = intent.getIntExtra("TestMode", 0);
        Log.i(TAG, "The value of TestMode is :" + TestMode);
        if(1 == TestMode)//AF Mode
        {
            mMode = intent.getIntExtra("AFMode", 0);
            switch(mMode){
                case 1:
                    captureMode1();
                    break;
                case 2:
                    captureMode2();
                    break;
                case 3:
                    captureMode3();
                    break;
                case 4:
                    captureMode4();
                    break;
            }
         }
         else if(2 == TestMode)//RawCapture Mode
         {
             RawCapture();
         }
         else//not select mode yet
         {
             Toast.makeText(this,"Please select the test mode first!",Toast.LENGTH_LONG).show();
         }
    }

    private void captureMode1()
    {           
        Log.i(TAG, "Enter captureMode1 function.");
        threadFirst = new mAFMode1FirstThread();
        threadFirst.start();
    }

    class mAFMode1FirstThread extends Thread{
        public void run(){
            Log.i(TAG, "mAFMode1FirstThread");
            mIsTest = true;

            mAFEngMode = 0;
            mCameraParam.set("afeng-mode", mAFEngMode);
            mCameraParam.set("focus-mode", "auto");
            mCameraParam.set("focus-meter", "spot");
            mCamera.setParameters(mCameraParam);
            mFocusStartTime = System.currentTimeMillis();
            mIsFocused = 0;
            mCamera.autoFocus(mAutoFocusCallback);

            mCanBack = false;
            takePicture();
            mAFEngMode = 1;
            mCameraParam.set("afeng-mode", mAFEngMode);
            mCameraParam.set("focus-mode", "manual");
            mCamera.setParameters(mCameraParam);
            mPos = 0;
            mCameraParam.set("afeng-pos", mPos);
            mCamera.setParameters(mCameraParam);
            startPreview();
            mCanBack = true;
            Sleep(2000);

            mHandler.sendEmptyMessage(MSG_AF_MODE1_EVENT);          

            Log.i(TAG, "mAFMode1FirstThread finish.");
        }
    }

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg){
            switch(msg.what){
                case MSG_AF_MODE1_EVENT:
                    mode1Thread = new AFMode1Thread();
                    mode1Thread.start();
                    break;
                case MSG_AF_MODE3_EVENT:
                    mode3Thread = new AFMode3Thread();
                    mode3Thread.start();
                    break;
                case MSG_AF_MODE4_EVENT:
                    mode4Thread = new AFMode4Thread();
                    mode4Thread.start();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    public void onBackPressed() {
        if(false == mCanBack){
            return;
        }
        super.onBackPressed();
    }

    class AFMode1Thread extends Thread{
        public void run(){
            Log.i(TAG, "mAFMode1Thread");
            if(true == mIsOnPause){
                mHandler.removeMessages(MSG_AF_MODE1_EVENT);
                return;
            }
            mCanBack = false;
            takePicture();
            mPos ++;
            mCameraParam.set("afeng-pos", mPos);
            mCamera.setParameters(mCameraParam);            
            startPreview();
            mCanBack = true;
            Sleep(2000);            
            if(false == mIsOnPause && mPos <= 50){
                mHandler.sendEmptyMessage(MSG_AF_MODE1_EVENT);
            }
            if(mPos > 50){
                mIsTest = false;
            }
        }
    }

    private void captureMode2()
    {   
        Log.i(TAG, "Enter captureMode2 function.");
        mode2Thread = new AFMode2Thread();
        mode2Thread.start();
    }

    class AFMode2Thread extends Thread{
        public void run(){
            Log.i(TAG, "mAFMode2Thread");

            mIsTest = true; 
            mCanBack = true;
            mAFEngMode = 1;
            mCameraParam.set("afeng-mode", mAFEngMode);
            mCameraParam.set("focus-mode", "fullscan");
            mCamera.setParameters(mCameraParam);
            mIsFocused = 0;
            mCamera.autoFocus(mAutoFocusCallback);
            mProgressDlgHandler.sendEmptyMessage(EVENT_FULL_SCAN_START);

            mCanBack = false;
            takePicture();
            startPreview();
            mCanBack = true;
            mIsTest = false;
            Sleep(2000);

        }
    }

    private void captureMode3()
    {
        Log.i(TAG, "Enter captureMode3 function.");
        mPos = 0;
        mode3Thread = new AFMode3Thread();
        mode3Thread.start();
    }

    class AFMode3Thread extends Thread{
        public void run(){
            Log.i(TAG, "mAFMode3Thread");
            if(true == mIsOnPause){
                mHandler.removeMessages(MSG_AF_MODE3_EVENT);
                return;
            }

            mIsTest = true;

            mAFEngMode = 1;
            mCameraParam.set("afeng-mode", mAFEngMode);
            mCameraParam.set("focus-mode", "fullscan");
            mCamera.setParameters(mCameraParam);
            mIsFocused = 0;
            mCamera.autoFocus(mAutoFocusCallback);
            mProgressDlgHandler.sendEmptyMessage(EVENT_FULL_SCAN_START);

            mCanBack = false;
            takePicture();
            mPos ++;
            startPreview();
            mCanBack = true;
            Sleep(2000);

            if(false == mIsOnPause && mPos <= 50){
                mHandler.sendEmptyMessage(MSG_AF_MODE3_EVENT);
            }
            if(mPos > 50){
                mIsTest = false;
            }
        }
    }

    private void captureMode4()
    {       
        Log.i(TAG, "Enter captureMode4 function.");
        mPos = 0;
        mode4Thread = new AFMode4Thread();
        mode4Thread.start();
    }

    class AFMode4Thread extends Thread{
        public void run(){
            Log.i(TAG, "mAFMode4Thread");
            if(true == mIsOnPause){
                mHandler.removeMessages(MSG_AF_MODE4_EVENT);
                return;
            }

            mIsTest = true;

            mAFEngMode = 0;
            mCameraParam.set("afeng-mode", mAFEngMode);
            mCameraParam.set("focus-mode", "auto");
            mCameraParam.set("focus-meter", "spot");
            mCamera.setParameters(mCameraParam);
            mIsFocused = 0;
            mCamera.autoFocus(mAutoFocusCallback);
            mCanBack = false;
            takePicture();
            mPos ++;
            startPreview();
            mCanBack = true;
            Sleep(2000);

            if(false == mIsOnPause && mPos <= 50){
                mHandler.sendEmptyMessage(MSG_AF_MODE4_EVENT);
            }
            if(mPos > 50){
                mIsTest = false;
            }
        }
    }

    private void RawCapture()
    {
        Log.i(TAG, "Enter RawCapture function.");
        mRawCaptureThread = new RawCaptureThread();
        mRawCaptureThread.start();
    }

    class RawCaptureThread extends Thread{
        public void run(){
            Log.i(TAG, "mAFMode4Thread");
            mCanBack = true;

            mIsTest = true;
            mIsRawCapture = true;

            mCameraParam.set("rawsave-mode", "on");
            long dateTaken = System.currentTimeMillis();
            mRawCaptureFileName = CAMERA_IMAGE_BUCKET_NAME + createName(dateTaken);
            mCameraParam.set("rawfname", mRawCaptureFileName + ".raw");
            mCamera.setParameters(mCameraParam);
            mCamera.autoFocus(mAutoFocusCallback);
            mCanBack = false;
            takePicture();
            startPreview();
            mCanBack = true;
            mIsRawCapture = false;
            mIsTest = false;
            Sleep(2000);            

        }
    }

    private final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback {
        public void onAutoFocus(boolean focused, android.hardware.Camera camera) {
            mFocusCallbackTime = System.currentTimeMillis();
            mIsFocused = 1;
            if(1 == mAFEngMode)
            {
                mProgressDlgHandler.sendEmptyMessage(EVENT_FULL_SCAN_COMPLETE);
            }
        }
    }
    private final class ShutterCallback implements android.hardware.Camera.ShutterCallback {
        public void onShutter() {           
            mShutterCallbackTime = System.currentTimeMillis();
        }
    }  
    private final class RawPictureCallback implements PictureCallback {
      public void onPictureTaken(byte [] rawData, android.hardware.Camera camera) {         
        mRawPictureCallbackTime = System.currentTimeMillis();
      }
    }
    private final class JpegPictureCallback implements PictureCallback {
      public void onPictureTaken(byte [] jpegData, android.hardware.Camera camera) {           
         mJpegPictureCallbackTime = System.currentTimeMillis();
         if (jpegData != null) {
            storeImage(jpegData);
         }
         mIsCapture = 0;
      }
    }

    private void takePicture() 
    {       
        while (mIsFocused == 0) {
            Sleep(100);
        }

        mIsCapture = 1;
        mCaptureStartTime = System.currentTimeMillis();
        mCamera.takePicture(mShutterCallback, mRawPictureCallback, new JpegPictureCallback());
        while (mIsCapture == 1) {
            Sleep(100);
        }
    }
    private void Sleep(long time) 
    {
        try{
            Thread.sleep(time);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    private void storeImage(byte[] jpegData) {
        long time;
        long dateTaken = System.currentTimeMillis();
        String name = CAMERA_IMAGE_BUCKET_NAME + createName(dateTaken) + ".jpg";

        if(true == mIsRawCapture)
        {
            name = mRawCaptureFileName  + ".jpg";
        }

        File fHandle = new File(name);
        try {
            OutputStream bos = new FileOutputStream(fHandle);
            bos.write(jpegData);
            bos.close();
            time = System.currentTimeMillis();
        } catch (Exception ex) {
            fHandle.delete();
        }
    }
    private static String createName(long dateTaken) {
        return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString();
    }

    OnClickListener mButtonHandler = new OnClickListener() {
        public void onClick(View v) {
            SharedPreferences sharedPre = getSharedPreferences("test_results", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPre.edit();

            if (v.getId() == R.id.camera_test_pass) {
                Log.i("CameraTest", "-----mButtonHandler----onClick()----camera_test_pass");
                editor.putBoolean("CameraTest", true);
            } else if (v.getId() == R.id.camera_test_fail) {
                Log.i("CameraTest", "-----mButtonHandler----onClick()----camera_test_fail");
                editor.putBoolean("CameraTest", false);
            }
            editor.commit();

            Intent intent = new Intent();
            intent.setClass(CameraTest.this, SpeakerTest.class);
            startActivity(intent);
            finish();
        }
    }; 

}

答案 2 :(得分:1)

//将拜耳转换为rgb的丑陋代码

//test__1604x1206_10_2b.raw
//test__1284x966_10_3.raw
#include <stdio.h>
    unsigned short int bayerImage[2500][3500]; //times 3 allows for forming an RGB image for debugging
    unsigned char bmpImage[30000000]; //times 3 allows for forming an RGB image for debugging
#include <iomanip>
#include <iostream>
#include "bayer2rgb.h"
#include <memory.h>
#include <string.h>

/*****************************************************************************
**
*/

int DumpImage( char* pszFilename, BYTE* pImage, int bmpWidth, int bmpHeight,int bmpBits,int bmpFormat)
{
    FILE     *bayerFile;
    FILE     *rgbFile;
    int x,y;
    unsigned char lowOrder,highOrder;
    unsigned char bmpchar;
    unsigned short bayerVal;

    unsigned char bmpheader[62];
    char  FullFilename[MY_MAX_PATH];
    unsigned int  bmrgbFilesize;
    unsigned int minPixel=100000;
    unsigned int maxPixel=0;
    static unsigned int rgbValues[4][1024];

    /*expecting 10 bit bayer */
    if(bmpBits!=10)
    {
        printf("invalid bit specification\n");
        return(-1);
    }
    if(bmpHeight >= 0)
    {
        bmrgbFilesize = (((bmpWidth*24+31)/32)*4)*bmpHeight;
    }
    else
    {
        bmrgbFilesize = (((bmpWidth*24+31)/32)*4)*(-bmpHeight);
    }

    #ifdef LINUX

      strcpy( FullFilename, pszFilename );

      rgbFile = fopen( FullFilename, "w+b" );

      if( rgbFile )

    #else

      strcpy_s( FullFilename, sizeof(FullFilename), pszFilename );

      errno_t  errno;
      errno = fopen_s( &bayerFile, FullFilename, "r+b" );  
      if(errno == 0)
      {
          printf("size %d", strlen(FullFilename)-4);
        memcpy(&FullFilename[strlen(FullFilename)-4],".bmp",4);
        errno = fopen_s( &rgbFile, FullFilename, "w+b" );  
      }
      if ( errno == 0 )
    #endif
    {

/*    0 1 2 3 4 5     0 1 2 3 4 5     0 1 2 3 4 5 */
/*  0 R G R G R G   0 G R G R G R   0 B G B G B G */
/*  1 G B G B G B   1 B G B G B G   1 G R G R G R */
/*  2 R G R G R G   2 G R G R G R   2 B G B G B G */
/*  3 G B G B G B   3 B G B G B G   3 G R G R G R */



        memset(bmpImage,255,sizeof(bmpImage));
        switch(bmpFormat)
        {
        case 2:
//            0 1 2 3 4 5
//          0 G R G R G R
//          1 B G B G B G
//          2 G R G R G R
//          3 B G B G B G
            for(y=0;y<bmpHeight;y++)
            {
                for(x=0;x<bmpWidth;x++)
                {
                    lowOrder=fgetc(bayerFile);
                    highOrder=fgetc(bayerFile);
                    bayerVal=(highOrder * 0x100);
                    bayerVal+=lowOrder;
                    bayerImage[y][x]=bayerVal;
                    if(bayerVal<minPixel)
                    {
                        minPixel=bayerVal;
                    }
                    if(bayerVal>maxPixel)
                    {
                        maxPixel=bayerVal;
                    }
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //green
                            bayerImage[y][x]=bayerVal/2;
                            //if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.65;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[0][bayerVal]++;
                        }
                        else
                        {
                            //red
                            bayerImage[y][x]=bayerVal/2;
                            //if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.85;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[1][bayerVal]++;
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //blue
                            bayerImage[y][x]=bayerVal/2;
                            //if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.85;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[2][bayerVal]++;
                        }
                        else
                        {
                            //green
                            bayerImage[y][x]=bayerVal/2;
                            //if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.65;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[3][bayerVal]++;
                        }
                    }
                 }
            }
            for(y=1;y<bmpHeight-1;y++)
            {
                for(x=1;x<bmpWidth-1;x++)
                {            
                    bmpchar=bayerImage[y][x]/4;
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //green pixel bayerImage[y][x]
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y-1][x]+bayerImage[y+1][x])/2;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y][x]/2)+((bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/8);//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y][x-1]+bayerImage[y][x+1])/2;//red
                        }
                        else
                        {
                            //red pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/4;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y-1][x]+bayerImage[y+1][x]+bayerImage[y][x-1]+bayerImage[y][x+1])/4;//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y][x]);//red
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //blue pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=bayerImage[y][x];//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y-1][x]+bayerImage[y+1][x]+bayerImage[y][x-1]+bayerImage[y][x+1])/4;//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/4;//red
                        }
                        else
                        {
                            //green pixel 
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x-1]+bayerImage[y][x+1])/2;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y][x]/2)+((bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/8);//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y-1][x]+bayerImage[y+1][x])/2;//red
                        }
                    }
                }
            }
            break;
        case 3:
            printf("format 3\n");
//            0 1 2 3 4 5
//          0 R G R G R G
//          1 G B G B G B
//          2 R G R G R G
//          3 G B G B G B
            for(y=0;y<bmpHeight;y++)
            {
                for(x=0;x<bmpWidth;x++)
                {
                    lowOrder=fgetc(bayerFile);
                    highOrder=fgetc(bayerFile);
                    bayerVal=(highOrder * 0x100);
                    bayerVal+=lowOrder;
                    bayerImage[y][x]=bayerVal;
                    if(bayerVal<minPixel)
                    {
                        minPixel=bayerVal;
                    }
                    if(bayerVal>maxPixel)
                    {
                        maxPixel=bayerVal;
                    }
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //red
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.85;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[1][bayerVal]++;
                        }
                        else
                        {
                            //green
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            bayerImage[y][x]*=.65;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[0][bayerVal]++;
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //green
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            bayerImage[y][x]*=.65;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[3][bayerVal]++;
                        }
                        else
                        {
                            //blue
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.85;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[2][bayerVal]++;
                        }
                    }
                 }
            }
            for(y=1;y<bmpHeight-1;y++)
            {
                for(x=1;x<bmpWidth-1;x++)
                {            
                    bmpchar=bayerImage[y][x]/4;
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //red pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/4;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y-1][x]+bayerImage[y+1][x]+bayerImage[y][x-1]+bayerImage[y][x+1])/4;//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=bayerImage[y][x];//red 
                        }
                        else
                        {
                            //green pixel bayerImage[y][x]
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y-1][x]+bayerImage[y+1][x])/2;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y][x]/2)+((bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/8);//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y][x-1]+bayerImage[y][x+1])/2;//red 
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //green pixel 
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x-1]+bayerImage[y][x+1])/2;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y][x]/2)+((bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/8);//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y-1][x]+bayerImage[y+1][x])/2;//red
                        }
                        else
                        {
                            //blue pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=bayerImage[y][x];//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y-1][x]+bayerImage[y+1][x]+bayerImage[y][x-1]+bayerImage[y][x+1])/4;//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/4;//red
                        }
                    }
                }
            }
            break;
        case 4:
//            0 1 2 3 4 5
//          0 G R G R G R
//          1 B G B G B G
//          2 G R G R G R
//          3 B G B G B G
            for(y=0;y<bmpHeight;y++)
            {
                for(x=0;x<bmpWidth;x++)
                {
                    lowOrder=fgetc(bayerFile);
                    highOrder=fgetc(bayerFile);
                    bayerVal=(highOrder * 0x100);
                    bayerVal+=lowOrder;
                    bayerImage[y][x]=bayerVal;
                    if(bayerVal<minPixel)
                    {
                        minPixel=bayerVal;
                    }
                    if(bayerVal>maxPixel)
                    {
                        maxPixel=bayerVal;
                    }
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //green
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            bayerImage[y][x]*=.65;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[0][bayerVal]++;
                        }
                        else
                        {
                            //red
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.85;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[1][bayerVal]++;
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //blue
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            //bayerImage[y][x]*=.85;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[2][bayerVal]++;
                        }
                        else
                        {
                            //green
                            bayerImage[y][x]=bayerVal;
                            if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            bayerImage[y][x]*=.65;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[3][bayerVal]++;
                        }
                    }
                 }
            }
            for(y=1;y<bmpHeight-1;y++)
            {
                for(x=1;x<bmpWidth-1;x++)
                {            
                    bmpchar=bayerImage[y][x]/4;
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //green pixel bayerImage[y][x]
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x]+bayerImage[y][x+1]+bayerImage[y+1][x])/3;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=bmpImage[(((y*bmpWidth)+x)*3)+0];//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=bmpImage[(((y*bmpWidth)+x)*3)+0];//red
                        }
                        else
                        {
                            //red pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x]+bayerImage[y][x+1]+bayerImage[y+1][x+1])/3;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=bmpImage[(((y*bmpWidth)+x)*3)+0];//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=bmpImage[(((y*bmpWidth)+x)*3)+0];//red
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //blue pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x]+bayerImage[y+1][x]+bayerImage[y+1][x+1])/3;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=bmpImage[(((y*bmpWidth)+x)*3)+0];//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=bmpImage[(((y*bmpWidth)+x)*3)+0];//red
                        }
                        else
                        {
                            //green pixel 
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x]+bayerImage[y][x+1]+bayerImage[y+1][x])/3;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=bmpImage[(((y*bmpWidth)+x)*3)+0];//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=bmpImage[(((y*bmpWidth)+x)*3)+0];//red
                        }
                    }
                }
            }
            break;
        case 5:
//            0 1 2 3 4 5
//          0 G R G R G R
//          1 B G B G B G
//          2 G R G R G R
//          3 B G B G B G
            for(y=0;y<bmpHeight;y++)
            {
                for(x=0;x<bmpWidth;x++)
                {
                    lowOrder=fgetc(bayerFile);
                    highOrder=fgetc(bayerFile);
                    bayerVal=(highOrder * 0x100);
                    bayerVal+=lowOrder;
                    bayerImage[y][x]=bayerVal;
                    if(bayerVal<minPixel)
                    {
                        minPixel=bayerVal;
                    }
                    if(bayerVal>maxPixel)
                    {
                        maxPixel=bayerVal;
                    }
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //green
                            bayerImage[y][x]=bayerVal;
                            //if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            bayerImage[y][x]/=256;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[0][bayerVal]++;
                        }
                        else
                        {
                            //red
                            bayerImage[y][x]=bayerVal;
                            //if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            bayerImage[y][x]/=256;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[1][bayerVal]++;
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //blue
                            bayerImage[y][x]=bayerVal;
                            //if (bayerImage[y][x] >= 10) bayerImage[y][x]-=10; else bayerImage[y][x]=0;
                            bayerImage[y][x]/=256;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[2][bayerVal]++;
                        }
                        else
                        {
                            //green
                            bayerImage[y][x]=bayerVal;
                            //if (bayerImage[y][x] >= 20) bayerImage[y][x]-=20; else bayerImage[y][x]=0;
                            bayerImage[y][x]/=256;
                            if(bayerImage[y][x]>255) 
                                bayerImage[y][x]=255;
                            rgbValues[3][bayerVal]++;
                        }
                    }
                 }
            }
            for(y=1;y<bmpHeight-1;y++)
            {
                for(x=1;x<bmpWidth-1;x++)
                {            
                    bmpchar=bayerImage[y][x]/4;
                    if(y%2==0)
                    {
                        if(x%2==0)
                        {
                            //green pixel bayerImage[y][x]
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y-1][x]+bayerImage[y+1][x])/2;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y][x]/2)+((bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/8);//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y][x-1]+bayerImage[y][x+1])/2;//red
                        }
                        else
                        {
                            //red pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/4;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y-1][x]+bayerImage[y+1][x]+bayerImage[y][x-1]+bayerImage[y][x+1])/4;//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y][x]);//red
                        }
                    }
                    else
                    {
                        if(x%2==0)
                        {
                            //blue pixel
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=bayerImage[y][x];//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y-1][x]+bayerImage[y+1][x]+bayerImage[y][x-1]+bayerImage[y][x+1])/4;//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/4;//red
                        }
                        else
                        {
                            //green pixel 
                            bmpImage[(((y*bmpWidth)+x)*3)+0]=(bayerImage[y][x-1]+bayerImage[y][x+1])/2;//blue
                            bmpImage[(((y*bmpWidth)+x)*3)+1]=(bayerImage[y][x]/2)+((bayerImage[y-1][x-1]+bayerImage[y-1][x+1]+bayerImage[y+1][x-1]+bayerImage[y+1][x+1])/8);//green
                            bmpImage[(((y*bmpWidth)+x)*3)+2]=(bayerImage[y-1][x]+bayerImage[y+1][x])/2;//red
                        }
                    }
                }
            }
            break;
        default:
            printf("undefined bit format\n");
            return(-3);
            break;
        }
        bmpheader[0]='\x42';
        bmpheader[1]='\x4d';
        bmpheader[2]='\x38';
        bmpheader[3]='\x00';
        bmpheader[4]='\x90';
        bmpheader[5]='\x00';
        bmpheader[6]='\x00';
        bmpheader[7]='\x00';

        bmpheader[8]='\x00';
        bmpheader[9]='\x00';
        bmpheader[10]='\x36';
        bmpheader[11]='\x00';
        bmpheader[12]='\x00';
        bmpheader[13]='\x00';
        bmpheader[14]='\x28';
        bmpheader[15]='\x00';

        bmpheader[16]='\x00';
        bmpheader[17]='\x00';
        bmpheader[18]='\x00';
        bmpheader[19]='\x08';
        bmpheader[20]='\x00';
        bmpheader[21]='\x00';
        bmpheader[22]='\x00';
        bmpheader[23]='\x06';

        bmpheader[24]='\x00';
        bmpheader[25]='\x00';
        bmpheader[26]='\x01';
        bmpheader[27]='\x00';
        bmpheader[28]='\x18';
        bmpheader[29]='\x00';
        bmpheader[30]='\x00';
        bmpheader[31]='\x00';

        bmpheader[32]='\x00';
        bmpheader[33]='\x00';
        bmpheader[34]='\x00';
        bmpheader[35]='\x00';
        bmpheader[36]='\x00';
        bmpheader[37]='\x00';
        bmpheader[38]='\x5a';
        bmpheader[39]='\x37';

        bmpheader[40]='\x00';
        bmpheader[41]='\x00';
        bmpheader[42]='\x5a';
        bmpheader[43]='\x37';
        bmpheader[44]='\x00';
        bmpheader[45]='\x00';
        bmpheader[46]='\x00';
        bmpheader[47]='\x00';

        bmpheader[48]='\x00';
        bmpheader[49]='\x00';
        bmpheader[50]='\x00';
        bmpheader[51]='\x00';
        bmpheader[52]='\x00';
        bmpheader[53]='\x00';

        memcpy(&bmpheader[2],&bmrgbFilesize,4);
        memcpy(&bmpheader[18],&bmpWidth,4);
        memcpy(&bmpheader[22],&bmpHeight,4);

        fwrite( bmpheader, 1, 54, rgbFile );

        fwrite( pImage, 1, bmrgbFilesize, rgbFile );
        fclose( rgbFile );
        fclose( bayerFile );
        return(1);
    }
    return(-2);

} // end DumpImage()


int main(int argc, char* argv[]) 
{

    if(argc !=2)
    {
        printf("wrong number of arugments\n");
        printf("drag file to decode on top of program icon\n");
        return(-1);
    }
    else
    {
        printf("%s\n",argv[0]);
        printf("%s\n",argv[1]);
    }
/*
char *str = "sdfadabcGGGGGGGGG";
char *result = strstr(str, "abc");
int position = result - str;
int substringLength = strlen(str) - position;
*/
    char *widthStr = strstr(argv[1],"__")+2;
    int widthInt=atoi(widthStr);

    char *heightStr = strstr(widthStr,"x")+1;
    int heightInt=atoi(heightStr);

    char *bitsStr = strstr(heightStr,"_")+1;
    int bitsInt=atoi(bitsStr);

    char *formatStr = strstr(bitsStr,"_")+1;
    int formatInt=atoi(formatStr);

    //DumpImage( argv[1], bmpImage, widthInt, heightInt,bitsInt,formatInt);
    DumpImage( argv[1], bmpImage, widthInt, heightInt,bitsInt,2);
    printf("done\n");
    return 1;
}