public classMainActivity extends Activity {
        private static final String TAG        = "MainActivity";
        private SurfaceView surfaceView;
        private Camera camera;        @Override
        public void onCreate(Bundle        savedInstanceState) {
                super.onCreate(savedInstanceState);                Window window = getWindow();
                requestWindowFeature                (Window.FEATURE_NO_TITLE);// 没有标题
                window.setFlags                (WindowManager.LayoutParams.FLAG_FULLSCREEN,
                                WindowManager.LayoutParams.                                FLAG_FULLSCREEN);// 设置全屏
                window.addFlags                (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 高亮                setContentView(R.layout.main);                surfaceView =                (SurfaceView) findViewById(R.id.surfaceView);                surfaceView.getHolder().setFixedSize(176, 144); // 设置分辨率
                /*
                 *
                 * 下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用
                 *
                 * 户面前
                 */
                surfaceView.getHolder().setType                (SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);                surfaceView.getHolder().addCallback(new SurfaceCallback());
        }        private final class SurfaceCallback implements        SurfaceHolder.Callback {
                private boolean preview;                @Override
                public void surfaceChanged                (SurfaceHolder holder, int format, int width,                int height) {
                }                @Override
                publicvoid surfaceCreated(SurfaceHolder holder) {
                        //打开摄像头
                        camera = Camera.open();
                       WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
                        Display display =wm.getDefaultDisplay();
                        Camera.Parametersparameters = camera.getParameters();
                       parameters.setPreviewSize(display.getWidth(), display.getHeight());//设置预览照片的大小
                        parameters.setPreviewFrameRate(3);//每秒3帧
                        parameters.setPictureFormat(PixelFormat.JPEG);//设置照片的输出格式
                       parameters.set("jpeg-quality", 85);//照片质量
                       parameters.setPictureSize(display.getWidth(), display.getHeight());//设置照片的大小
                        camera.setParameters(parameters);
                       try {
                               camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面
                                camera.startPreview();
                               preview = true;
                        } catch(IOException e) {
                                Log.e(TAG, e.toString());
                        }
                }                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {                        if (camera != null) {
                                if (preview) {                                        camera.stopPreview();                                }
                                camera.release();                        }
                }        }        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
                if                (camera != null && event.getRepeatCount() == 0) {
                        switch                        (keyCode) {
                        case KeyEvent.KEYCODE_SEARCH:// 搜索键                                // 自动对焦                                camera.autoFocus(null);
                                return true;                        case KeyEvent.KEYCODE_CAMERA:// 拍照键                        case KeyEvent.KEYCODE_DPAD_CENTER:// 确定键                                camera.takePicture(null, null, new TakePictureCallback());                                return true;
                        }
                }                return super.onKeyDown(keyCode, event);
        }        private final class TakePictureCallback implements PictureCallback {                @Override
                public void onPictureTaken(byte[] data,                Camera camera) {
                        try {                                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                                                data.length);                                File file = new File                                (Environment.getExternalStorageDirectory(), System
                                                .currentTimeMillis()
                                                +                                                ".jpg");
                                FileOutputStream outStream =                                new FileOutputStream(file);                                bitmap.compress(CompressFormat.JPEG, 100, outStream);                                outStream.close();                                camera.stopPreview();
                                camera.startPreview();                        } catch (Exception e) {                                Log.e(TAG, e.toString());
                        }
                }        }}  <?xml version="1.0" encoding="utf-8" ?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" androidrientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
  <SurfaceView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/surfaceView" />
  </LinearLayout>

解决方案 »

  1. http://www.blogjava.net/MEYE/articles/331520.html
    bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法
      

  2. Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
      data.length);  File file = new File  (Environment.getExternalStorageDirectory(), System
      .currentTimeMillis()
      +  ".jpg");
      FileOutputStream outStream =  new FileOutputStream(file);  bitmap.compress(CompressFormat.JPEG, 100, outStream);  outStream.close();
       if(bitmapObject.isRecycled()==false) //如果没有回收   
             bitmapObject.recycle();    

      camera.stopPreview();
      camera.startPreview();
      

  3. 回收只是通知系统,但是不会马上回收的。如果慢了,那你又new了,那就溢出了
    你每次taken的时候都去new一个bitmap,这样很容易溢出。
    最好是弄一个全局的bitmap,然后每次只是往这个bitmap上画,当然,要先清空内容。bitmap的大小可以直接以屏幕的宽高来create
      

  4. 哎 这问题搜一下不一大堆吗
    用BitmapFactory.decodeStream 这个是用NATIVE的方法去生成bitmap,其他的是JAVA调用库生成的,所以容易buffer exceed
      

类似问题 »