位图VM内存错误

时间:2011-10-13 10:25:37

标签: android

我有一个应用程序,它采用预览框架并将其保存为图片。它完全正常工作,除了在我退出应用程序并尝试再次运行它之后,它将始终强制关闭并且错误是内存的java.lang.out。谁知道有什么问题?下面是我的代码和我的logcat。

public class SymbolCamera extends Activity implements SurfaceHolder.Callback {
/** Called when the activity is first created. */
Camera camera;
Camera.Parameters params;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
TextView tv;
int flag = 0;
//int width, height;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.color_camera_main);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    getWindow().setFormat(PixelFormat.UNKNOWN);
    surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    controlInflater = LayoutInflater.from(getBaseContext());
    View viewControl = controlInflater.inflate(R.layout.statistics, null);
    LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
    this.addContentView(viewControl, layoutParamsControl);

     tv = (TextView)findViewById(R.id.info);
     tv.setText("SymbolCamera");
}

public boolean onCreateOptionsMenu(Menu menu)
{
 MenuInflater inflater = getMenuInflater();
 inflater.inflate(R.menu.option_menu_symbol, menu);
 return true;
}

public boolean onOptionsItemSelected(MenuItem item)
{
    Intent intent;
    if(camera != null) 
    {
        camera.setPreviewCallback(null);
        camera.release();
        camera = null;
    }

     switch(item.getItemId())
     {
     case R.id.gps:
         intent = new Intent(getApplicationContext(), GPSActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         startActivity(intent);
         finish();
         return true;
     case R.id.color:
         intent = new Intent(getApplicationContext(), ColorCameraActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         startActivity(intent);
         finish();
         return true;
     }

     return super.onOptionsItemSelected(item);
}

@Override
public void onPause() {
    super.onPause();

    if(camera != null) {
        //camera.setPreviewCallback(null);
        camera.release();
        previewing = false;
    }
}

Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

    @Override
    public void onAutoFocus(boolean arg0, Camera mCamera) {
        // TODO Auto-generated method stub

    }
};

Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {

    @Override
    public void onPreviewFrame(byte[] data, Camera mCamera) {

        // TODO Auto-generated method stub

        if(flag == 5)
        {
            camera.autoFocus(mAutoFocusCallback);
            camera.setPreviewCallback(null);
        }
        int ARRAY_LENGTH = params.getPreviewSize().width*params.getPreviewSize().height*3/2;
        int argb8888[] = new int[ARRAY_LENGTH]; 
        decodeYUV(argb8888,  data, params.getPreviewSize().width, params.getPreviewSize().height);
        Bitmap bitmap = Bitmap.createBitmap(argb8888, params.getPreviewSize().width, params.getPreviewSize().height, Config.ARGB_8888);

         if(flag == 5) {
            SymbolDetection symDet = new SymbolDetection(bitmap);
             String link =  symDet.run();
             tv.setText(link);
             symDet = null;

         }
         bitmap.recycle();
         flag++;

        /*FileOutputStream fos;
        try {
            fos = new FileOutputStream(String.format(Environment.getExternalStorageDirectory().toString() + "/testImage/%d.jpg", System.currentTimeMillis()));
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bitmap.compress(CompressFormat.JPEG, 75, bos);
            bos.flush();
            bos.close();
            fos.close();
            bitmap = null;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
    }
};

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub

    /*if(previewing)
    {
        try
        {
            camera.setPreviewDisplay(null);
            camera.setPreviewCallback(null);
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        camera.stopPreview();
        camera.release();
        previewing = false;
    }*/

    if(camera != null)
    {
        try {
            tv.setText("start camera");
            //params.setPreviewSize(width, height);
            camera.setPreviewCallback(mPreviewCallback);
            camera.setParameters(params);
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            previewing = true;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
    // TODO Auto-generated method stub
    camera = Camera.open();
    params = camera.getParameters();
    //width = params.getPreviewSize().width;
    //height = params.getPreviewSize().height;

}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
    // TODO Auto-generated method stub
    if(previewing && camera != null)
    {
        try {
            camera.setPreviewCallback(null);
            camera.setPreviewDisplay(null);
            camera.stopPreview();
            camera.release();
            camera = null;

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    previewing = false;
}


// decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android 
// David Manpearl 081201 
public void decodeYUV(int[] out, byte[] fg, int width, int height)
        throws NullPointerException, IllegalArgumentException {
    int sz = width * height;
    if (out == null)
        throw new NullPointerException("buffer out is null");
    if (out.length < sz)
        throw new IllegalArgumentException("buffer out size " + out.length
                + " < minimum " + sz);
    if (fg == null)
        throw new NullPointerException("buffer 'fg' is null");
    if (fg.length < sz)
        throw new IllegalArgumentException("buffer fg size " + fg.length
                + " < minimum " + sz * 3 / 2);
    int i, j;
    int Y, Cr = 0, Cb = 0;
    for (j = 0; j < height; j++) {
        int pixPtr = j * width;
        final int jDiv2 = j >> 1;
        for (i = 0; i < width; i++) {
            Y = fg[pixPtr];
            if (Y < 0)
                Y += 255;
            if ((i & 0x1) != 1) {
                final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
                Cb = fg[cOff];
                if (Cb < 0)
                    Cb += 127;
                else
                    Cb -= 128;
                Cr = fg[cOff + 1];
                if (Cr < 0)
                    Cr += 127;
                else
                    Cr -= 128;
            }
            int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
            if (R < 0)
                R = 0;
            else if (R > 255)
                R = 255;
            int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1)
                    + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
            if (G < 0)
                G = 0;
            else if (G > 255)
                G = 255;
            int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
            if (B < 0)
                B = 0;
            else if (B > 255)
                B = 255;
            out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
        }
    }

}
}

logcat的:

10-13 18:22:29.017: ERROR/AndroidRuntime(32260): FATAL EXCEPTION: main
10-13 18:22:29.017: ERROR/AndroidRuntime(32260): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at    android.graphics.Bitmap.nativeCreate(Native Method)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at   android.graphics.Bitmap.createBitmap(Bitmap.java:513)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at android.graphics.Bitmap.createBitmap(Bitmap.java:533)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at com.augmented.reality.SymbolCamera$2.onPreviewFrame(SymbolCamera.java:129)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at android.hardware.Camera$EventHandler.handleMessage(Camera.java:547)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at android.os.Looper.loop(Looper.java:130)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at android.app.ActivityThread.main(ActivityThread.java:3703)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at java.lang.reflect.Method.invokeNative(Native Method)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at java.lang.reflect.Method.invoke(Method.java:507)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
10-13 18:22:29.017: ERROR/AndroidRuntime(32260):     at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

我有同样的问题所以我写了一个特殊的位图管理器,你可以找到here