Android相机为一些用户拍摄多行内嵌的图片
1)我的应用程序的一些用户正在采取一些看起来像这样的窃听图片:
http://lh3.ggpht.com/i_VKS_Z1Ike5V8gEySiscQRRNkLwZMvv1a6u9diJrkWWGgYXUS-kqqxvAylhLIEJ1gs3MMZSEYIJJ4hX
我做的唯一事情就是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)。
我真的希望有人能够解释为什么图片看起来很不自在。
我无法告诉你为什么你从某些设备而不是其他设备看到乱码数据,但是我可以建议一种解决方法,它似乎可以成功地为我的应用程序工作。
您的示例代码将相机的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);
为我工作。
链接地址: http://www.djcxy.com/p/8119.html上一篇: Android Camera takes multi lined bugged picture for some users
下一篇: Android VideoView, seamless playback during orientation change