[英]Android Camera takes multi lined bugged picture for some users
1)我的應用程序的一些用戶正在拍攝一些看起來像這樣的錯誤圖片:
我唯一做的是jpegCallback中的標准位圖API:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 4;
bm = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
bm = Bitmap.createScaledBitmap(bm , 640, 480, true);
然后將其寫在磁盤上
imageFile = new File("/sdcard/app_dir/upload.jpg");
FileOutputStream outStream = new FileOutputStream(imageFile);
bm.compress(CompressFormat.JPEG, 75, outStream);
outStream.flush();
outStream.close();
2)編輯:我已經刪除了對setPreviewSize的調用,就像在那里解釋一樣: Android:從相機中保存的Jpeg看起來已損壞
我認為這對一些用戶(Desire HD)有幫助,但我可以告訴其他人仍然有問題(Desire S)。
我真的希望有人可以解釋為什么pics首先看起來像dindrded。
好吧,看起來你在從字節數組中解碼位圖時出現了圖像大小的錯誤。 您可以發布用於以下的代碼: - 設置相機 - 設置解碼參數 - 檢索圖像數據
我不能告訴你為什么你從某些設備而不是其他設備獲得亂碼數據,但我可以建議一個似乎在我的應用程序中成功運行的解決方法。
您的示例代碼將相機的JPEG縮小到640x480,然后將其保存到SD卡。 所以我猜你不需要全尺寸的相機圖像。
如果這個假設成立,你可以完全跳過Camera的takePicture()
API,只需將預覽幀保存到SD卡。 最簡單的方法是使用setOneShotPreviewCallback()
:
mCamera.setOneShotPreviewCallback( new StillPictureCallback() );
這將調用一次,並從攝像機返回數據緩沖區:
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);
}
}
回調調用后台任務來壓縮數據並將其保存到文件中。 我遺漏的唯一代碼是通過getCameraInfo()
查詢相機的預覽幀格式,寬度和高度的部分。 另請注意,Android YUVImage類是隨Froyo引入的,因此如果您需要支持早期版本的Android,則需要滾動自己的轉換代碼(StackOverflow上有示例)。
/**
* Background task to compress captured image data and save to JPEG file.
*
*/
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);
// Use the preview image format, as documented in Android SDK javadoc
if ( (mPreviewImageFormat == ImageFormat.NV21) || (mPreviewImageFormat == ImageFormat.YUY2) ) {
saveYUVToJPEG( mCamera, out, data );
} else if (mPreviewImageFormat == ImageFormat.JPEG) {
Log.d(TAG, "directly write JPEG to storage");
out.write(data);
} else {
Log.d(TAG, "try decoding to byte array");
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if ( bitmap != null ) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
} else {
Log.e(TAG, "decodeByteArray failed, no decoded data");
}
}
}
catch (FileNotFoundException ignore) {;}
catch (IOException ignore) {;}
finally {
if ( out != null ) {
try {
out.close();
} catch (IOException ignore) {;}
out = null;
}
if ( bitmap != null ) {
bitmap.recycle();
bitmap = null;
}
data = null;
}
return null;
}
}
/**
* Save YUV image data (aka NV21 or YUV420sp) data to JPEG file.
*
* @param camera
* @param out
* @param data
*/
protected void saveYUVToJPEG( Camera camera, FileOutputStream out, byte[] data ) {
YuvImage yuvimg = null;
try {
int width = mPreviewWidth;
int height = mPreviewHeight;
Rect rect = new Rect();
rect.left = 0;
rect.top = 0;
rect.right = width - 1;
rect.bottom = height - 1; // The -1 is required, otherwise a buffer overrun occurs
yuvimg = new YuvImage(data, mPreviewImageFormat, width, height, null);
yuvimg.compressToJpeg(rect, 90, out);
} finally {
yuvimg = null;
}
}
我在HTC Desire S上遇到了完全相同的問題。
我按照設置更新了移動系統 - >關於手機 - >軟件更新
我還實現了以下代碼:
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setParameters(parameters);
為我工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.