簡體   English   中英

Android Camera為一些用戶提供了多行的錯誤圖片

[英]Android Camera takes multi lined bugged picture for some users

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)。

我真的希望有人可以解釋為什么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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM