CropImageView Transaction太大异常

时间:2017-01-13 15:35:27

标签: android android-intent

我遇到与cropImageView相关的事务太大异常的问题。任何时候我使用cropImageView裁剪图像然后使用intent更改活动,它会给我一个Transaction太大的异常。

我继续看到它可能是因为我将过多的数据从一个活动传递到另一个活动但是即使我把我的代码的一部分传递给意图中的一个字节数组它仍然会因事务太大而崩溃异常。

这是我的代码:

public class TestActivity extends AppCompatActivity {

private CropImageView cropImageView;
private Button cropImage;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    cropImage = (Button) findViewById(R.id.cropImage);
    cropImageView = (CropImageView) findViewById(R.id.cropImageView);

    Intent intent = getIntent();
    byte[]  bite = intent.getExtras().getByteArray("imageForCropping");

    Bitmap bitmap = getPhoto(bite);

    cropImageView.setImageBitmap(bitmap);

    cropImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Bitmap bit = cropImageView.getCroppedImage();
            byte[] byteArray = getBytes(bit);
            Intent intent = new Intent(TestActivity.this, HomeScreenActivity.class);
            intent.putExtra("croppedImage", byteArray);
            TestActivity.this.startActivity(intent);

        }
    });



}

public static Bitmap getPhoto(byte[] image) {
    return BitmapFactory.decodeByteArray(image, 0, image.length );

}

public static byte[] getBytes(Bitmap image) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.PNG, 100, stream);
    return stream.toByteArray();
}

}

我试图避免使用此意图通过使用sqlite数据库传递字节数组,但它仍然因事务太大而异常崩溃。所以这让我相信CropImageView导致了这个问题。

如果您知道问题可能,请告诉我。

提前致谢!

2 个答案:

答案 0 :(得分:1)

这是cropImageView中的一个错误,它会在调用onSaveInstanceState()时尝试将图像保存为自己的视图状态。

解决方案是将图像保存到文件中,并在调用setImageBitmap(null)之前调用裁剪图像视图上的super.onSaveInstanceState(),然后在需要时从文件中恢复图像位图。

编辑:好的,我会在此分享我的代码,但这真的很酷。我很高兴它有效。此外,它来自相机,所以我拍摄了照片并将位图作为字节数组。

请注意提醒。

@Override
public void onResume() {
    if(cameraPresenter != null) {
        cameraPresenter.onResume();
    }
    if(takenBitmap != null && !takenBitmap.isRecycled()) {
        takenPhotoDisplay.setImageBitmap(takenBitmap);
    }
}

@Override
public void onViewDestroyed(boolean removedByFlow) {
    takenPhotoDisplay.setImageBitmap(null);
}

@Override // called before `Activity super.onSaveInstanceState()`
public void preSaveViewState(Bundle bundle) {
    takenPhotoDisplay.setImageBitmap(null);
}

private byte[] takenPhoto;
private Bitmap takenBitmap;


private void restoreBitmap() {
    try {
        takenPhoto = readByteArrayFromFile("TEMP");
    } catch(FileNotFoundException e) {
        Log.e(TAG, "No bitmap found to restore");
    } catch(IOException e) {
        Log.e(TAG, "Could not read bitmap");
    }
}

private byte[] readByteArrayFromFile(String fileName)
        throws IOException {
    Context context = CustomApplication.get();
    byte[] result = null;
    FileInputStream fileInputStream = null;
    try {
        fileInputStream = context.openFileInput(fileName);
        result = IOUtils.toByteArray(fileInputStream);
    } catch(FileNotFoundException e) {
        Log.e(TAG, "The file was not found [" + fileName + "]", e);
        throw e;
    } catch(IOException e) {
        Log.e(TAG, "Unable to read data from stream [" + fileName + "]", e);
        throw e;
    } finally {
        if(fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch(IOException e) {
                Log.e(TAG, "Could not close.");
            }
        }
    }
    return result;
}


private void preserveBitmap() {
    if(takenPhoto != null) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = CustomApplication.get().openFileOutput("TEMP", Context.MODE_PRIVATE);
            fileOutputStream.write(takenPhoto);
        } catch(FileNotFoundException e) {
            Log.e(TAG, "Could not open temp");
        } catch(IOException e) {
            Log.e(TAG, "Could not write temp");
        } finally {
            if(fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch(IOException e) {
                    Log.e(TAG, "Nobody cares!");
                }
            }
        }
    }
}

private void destroyCurrentBitmap() {
    if(takenBitmap != null) {
        takenPhotoDisplay.setImageBitmap(null);
        takenBitmap.recycle();
        takenBitmap = null;
        takenPhoto = null;
        Runtime.getRuntime().gc();
    }
}

private void handleTakenPhoto(byte[] data) {
    CameraView.this.takenPhoto = data;
    if(takenPhoto != null) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap bm = BitmapFactory.decodeByteArray(takenPhoto, 0, takenPhoto.length, options);
        Log.d(TAG, "The Bitmap has width [" + bm.getWidth() + "] and height [" + bm.getHeight() + "]");
        // Setting post rotate to 90
        Matrix mtx = new Matrix();
        Log.i(TAG, "CURRENT ROTATION ANGLE: [" + getRotationAngle() + "]");
        // Rotating Bitmap
        mtx.postRotate(getRotationAngle());
        // Flipping bitmap
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(getActiveCameraId(), info);
        if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            mtx.postScale(-1, 1, bm.getWidth() / 2, bm.getHeight() / 2);
        }
        Runtime.getRuntime().gc();
        Bitmap newBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mtx, true);
        if(bm != newBitmap) {
            bm.recycle();
            bm = newBitmap; //yes, this is on purpose!
            Runtime.getRuntime().gc();
        } else {
            Log.i(TAG, "The created bitmap is the same as the previous one.");
        }
        bm = newBitmap; //yes, this is on purpose!
        takenBitmap = bm;
        if(takenBitmap != null && !takenBitmap.isRecycled()) {
            takenPhotoDisplay.setImageBitmap(takenBitmap);
        } else {
            Log.w(TAG, "The bitmap in [takenBitmap] is recycled!");
            takenPhotoDisplay.setImageBitmap(null);
        }
    } else {
        Log.w(TAG, "The taken photo is NULL.");
    }
}

//IMAGE ROTATION FIX
public int getRotationAngle(int cameraId) {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    Activity activity = ActivityUtils.getActivity(getContext());
    WindowManager windowManager = activity.getWindowManager();
    Display defaultDisplay = windowManager.getDefaultDisplay();
    int rotation = defaultDisplay.getRotation();
    int degrees = 0;
    switch(rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;
    }
    int result;
    //if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
    //    result = (info.orientation + degrees) % 360;
    //    result = (360 - result) % 360; // compensate the mirror
    //} else { // back-facing
    //    result = (info.orientation - degrees + 360) % 360;
    //}
    if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            result = (info.orientation - degrees + 540) % 360;
        } else {
            result = (info.orientation - degrees + 360) % 360;
        }
    } else {
        result = (info.orientation - degrees + 360) % 360;
    }
    return result;
}

答案 1 :(得分:0)

不要在意图或任何地方传递图像的字节。将其保存在磁盘上,仅传递URI,并从磁盘读取图像