I canโt tell you why you are getting corrupted data from some devices and not others, but I can offer a workaround that seems to work successfully for my application.
Your sample code scales a JPEG camera to 640x480 before saving it to an SD card. Therefore, I assume that you do not need a full-sized image of the camera.
If this assumption is correct, you can completely skip Camera takePicture() API and just save the preview frame to the SD card. The easiest way to do this is setOneShotPreviewCallback() :
mCamera.setOneShotPreviewCallback( new StillPictureCallback() );
This will be called once and send you a data buffer from the camera:
private class StillPictureCallback implements Camera.PreviewCallback { @Override public void onPreviewFrame(byte[] data, Camera camera) { mPictureTask = new SaveStillPictureTask(); byte[] myData = null; if ( data != null ) { myData = data.clone(); } mPictureTask.execute(myData); } }
The callback invokes a background task to compress the data and save it to a file. The only bit of code that I leave is the part that asks the camera for the preview frame format, width and height using getCameraInfo() . Also note that the Android class YUVImage was introduced with Froyo, so if you need to support earlier versions of Android, you will need to roll your own conversion code (there are examples on StackOverflow here).
private class SaveStillPictureTask extends AsyncTask<byte[], Void, Void> { private static final String TAG="VideoRecorder.SaveStillPictureTask"; @Override protected Void doInBackground(byte[]... params) { byte[] data = params[0]; FileOutputStream out = null; Bitmap bitmap = null; if ( data == null ) { Log.e(TAG, "doInBackground: data is null"); return null; } try { out = new FileOutputStream(mSnapshotFilePath);
mportuesisf
source share