如何以编程方式拍摄照片

时间:2011-11-30 11:04:54

标签: android android-camera

我正在开发一个应用程序,它可以在服务器调用时获取图像并将该图像发送到服务器。以下是我定义的CameraSurfaceView类中的一些代码。

private SurfaceHolder holder;
private Camera camera;        
private Bitmap osb;
public void takeImage(){
    Camera camera = this.getCamera();
    CameraSurfaceView.HandlePictureStorage c = this.new HandlePictureStorage();
    camera.takePicture(null, null, c);
}
public byte[] getImage(String type) {    
    if (osb==null) {
        System.err.println("Camera.getImage: osb NULL");
        return  null;
    }

    CompressFormat format = CompressFormat.JPEG;
    if (type.equals("PNG")) {
        format = CompressFormat.PNG;
    }

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        System.err.println("Camera.getImage: decoded");
        osb.compress(format, 100, out);
        System.err.println("Camera.getImage: compressed");
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } finally {
        //lock.unlock();
    }

    byte[] bytes = out.toByteArray();
    return bytes;
}


public void saveImage(byte[] picture) {
    System.err.println("saveImage");
    osb = BitmapFactory.decodeByteArray(picture, 0, picture.length);
}

和内部类HandlePictureStorage实现PictureCallBack

@Override
public void onPictureTaken(byte[] picture, Camera camera) 
{                    
    CameraSurfaceView.this.saveImage(picture);
}

当我从外部调用takeImage()然后调用getImage()函数时,我希望onPictureTaken(byte[] picture, Camera camera)之后的HandlePictureStorage takeImage()上的代码会立即执行保存图像,在getImage()之前,getImage()要检索数据。


不幸的是,当我在logcat上看到getImage()函数在takeImage()之后和onPictureTaken()之前运行时。因此,很明显takeImage只能得到空数据,因为以前没有保存过图片。 如果再次运行takeImage()getImage(),则函数getImage()将返回上一张照片的图片。

2 个答案:

答案 0 :(得分:5)

    CameraProjectActivity.java ----> main activity

    public class CameraProjectActivity extends Activity 
    {
        public static ImageView image;
        private Button btn_camera;

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

            image = (ImageView) findViewById(R.id.image);

            btn_camera = (Button) findViewById(R.id.btn_camera);
            btn_camera.setOnClickListener(new View.OnClickListener() 
            {

                @Override
                public void onClick(View v)
                {
                    Intent i = new Intent(CameraProjectActivity.this,CameraView.class);
                    startActivityForResult(i, 999);
                }

            });
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent intent) 
        {
           if(requestCode==999)
           {
               if(resultCode==585)
               {
                   //Intent Works
               }
               else
               {
                   alert("Picture not Captured!");
               }
           }
        }

        private void alert(String string) 
        {
            AlertDialog.Builder alert=new AlertDialog.Builder(CameraProjectActivity.this);
            alert.setMessage(string);
            alert.setTitle("Alert");
            alert.setNeutralButton("Ok",null);
            alert.show();
        }
    }

    CameraView.java

    public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener
    {
        private static final String TAG = "CameraTest";
        Camera mCamera;
        boolean mPreviewRunning = false;

        public void onCreate(Bundle icicle) 
        {
            super.onCreate(icicle);
            Log.e(TAG, "onCreate");

            getWindow().setFormat(PixelFormat.TRANSLUCENT);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setContentView(R.layout.cameraview);
            mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
            mSurfaceView.setOnClickListener(this);
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) 
        {
            super.onRestoreInstanceState(savedInstanceState);
        }


        Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {

            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                // TODO Auto-generated method stub
                if (data != null) 
                {
                    //Intent mIntent = new Intent();
                    //mIntent.putExtra("image",imageData);

                    mCamera.stopPreview();
                    mPreviewRunning = false;
                    mCamera.release();

                     try
                       {
                       BitmapFactory.Options opts = new BitmapFactory.Options();
                       Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length,opts);
                       bitmap = Bitmap.createScaledBitmap(bitmap, 480, 480, false);
                       CameraProjectActivity.image.setImageBitmap(bitmap);
                       }
                       catch(Exception e)
                       {
                             e.printStackTrace();
                       }
                    //StoreByteImage(mContext, imageData, 50,"ImageName");
                    //setResult(FOTO_MODE, mIntent);
                    setResult(585);
                    finish();
                }       
            }
        };




        protected void onResume() 
        {
            Log.e(TAG, "onResume");
            super.onResume();
        }

        protected void onSaveInstanceState(Bundle outState) 
        {
            super.onSaveInstanceState(outState);
        }

        protected void onStop() 
        {
            Log.e(TAG, "onStop");
            super.onStop();
        }

        public void surfaceCreated(SurfaceHolder holder) 
        {
            Log.e(TAG, "surfaceCreated");
            mCamera = Camera.open();
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            Log.e(TAG, "surfaceChanged");

            // XXX stopPreview() will crash if preview is not running
            if (mPreviewRunning) 
            {
                mCamera.stopPreview();
            }

            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try 
            {
                mCamera.setPreviewDisplay(holder);
            } 
            catch (Exception e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.e(TAG, "surfaceDestroyed");
            //mCamera.stopPreview();
            //mPreviewRunning = false;
            //mCamera.release();
        }

        private SurfaceView mSurfaceView;
        private SurfaceHolder mSurfaceHolder;

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mCamera.takePicture(null, mPictureCallback, mPictureCallback);
        }
    }

    cameraview.xml

    <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:orientation="vertical">
        <SurfaceView android:id="@+id/surface_camera"
            android:layout_width="fill_parent" android:layout_height="10dip"
            android:layout_weight="1">      
        </SurfaceView>  
    </LinearLayout>

    main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <Button android:id="@+id/btn_camera" 
            android:text="Take a Picture from Camera"
            android:layout_height="wrap_content" 
            android:layout_width="wrap_content"
            android:gravity="center"
            >
            </Button>
            <ImageView 
            android:layout_height="480px" 
            android:layout_width="480px"
            android:scaleType="fitXY"
            android:id="@+id/image"
            android:src="@drawable/android"
            />
    </LinearLayout>

// Dont forgot to add the below code in AndroidManifest.xml
// <uses-permission android:name="android.permission.CAMERA"></uses-permission>
//    <uses-feature android:name="android.hardware.camera" />
// <uses-feature android:name="android.hardware.camera.autofocus" />

答案 1 :(得分:0)

相机应用程序在一个单独的过程中运行,并且您的回调将在以后执行(例如,它会训练自动对焦,触发闪光,编码JPEG - 这需要时间)并且您无法控制持续时间。所以,你必须改变控制流程。为什么不从图片回调中调用你的getImage()?