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