7
votes

L'appareil photo Android prend une image multi-doublée bogues pour certains utilisateurs

  1. Certains utilisateurs de mon application prennent des images bogues qui ressemblent à celle-là:

     Entrez la description de l'image ici

    La seule chose que je fais est une API bitmap standard dans jpegcallback: xxx

    et Ensuite, écrivez-le sur le disque xxx

    1. Edit: J'ai supprimé un appel à SetPreviewsize comme Expliquer là-bas: Android: JPEG enregistré à partir de la caméra a l'air corrompu

      Je pense que cela a aidé pour certains utilisateurs (désir HD), mais je peux dire que les autres ont toujours la question (désir s).

      Je souhaite vraiment que quelqu'un puisse expliquer la raison pour laquelle Les photos ont l'air dérisée en premier lieu.


3 commentaires

Mon onglet Galaxy obtient une sortie similaire lors de la discussion QIK avec d'autres onglets Galaxy, vous n'êtes donc pas le seul à avoir ce problème.


Bug similaire avec une solution possible Stackoverflow.com/ Questions / 5540981 / ...


J'ai eu le même problème avec HTC Desire HD. Résolu par définir les valeurs p.sepreviefsize (optimalpreviewsize.width, optimalpreviewsize.height); et p.setpicturesize (optimalpicturesize.width, optimalpicturesize.height);


3 Réponses :


1
votes

Eh bien, on dirait que vous avez commis une erreur avec une taille d'image lors du décodage bitmap à partir de la matrice d'octet. Pouvez-vous poster le code que vous utilisez pour: - Configuration de la caméra - Configuration des paramètres de décodage - récupération des données d'image


0 commentaires

1
votes

Je ne peux pas vous dire pourquoi vous obtenez des données brouillées de certains appareils et non d'autres, mais je peux suggérer une solution de contournement qui semble fonctionner avec succès pour mon application.

Votre exemple de code achève la caméra JPEG Down à 640x480 avant de l'enregistrer sur la carte SD. Donc, je suppose que vous n'avez pas besoin de l'image de la caméra pleine de taille. P>

Si cette hypothèse est vraie, vous pouvez ignorer l'API de la caméra () CODE> API entièrement, et simplement sauvegarder Un cadre d'aperçu de la carte SD. Le moyen le plus simple de faire est avec setoneshotpreviewcallback () code>: p> xxx pré>

Ceci sera invoqué une fois et remettez votre mémoire tampon de données de la caméra : P>

/**
 * 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;
    }
}


3 commentaires

Je vais vous donner la prime à la fin de ce soir. Bien que ce ne soit pas la réponse même que j'attends, je vous donne des crédits pour m'appuyer sur le rappel OnePreview. Sur une note de côté, un de mes amis qui est un expert sur ces problématiques disent que c'est une question commune JPEG. Je n'ai pas eu le temps de travailler sur cela pour confirmer encore


Je pense que vous évitez surtout le problème de la JPEG avec cette approche. Sur presque tous les appareils que j'ai vus, vous obtenez les données comme imageFormat.nv21 (données brutes), puis effectuez un codage JPEG dans votre propre code.


NV21 est format par défaut et pris en charge (doit être) sur chaque téléphone. Prenez soin de vous, c'est-à-dire que la caméra annonce une certaine taille de prévisualisation que cela ne signifie pas qu'il est effectivement pris en charge.



1
votes

J'ai eu le même problème sur un HTC Desire S.

J'ai mis à jour le système mobile par paramètres -> À propos du téléphone -> Mises à jour logicielles

J'ai également implémenté le code suivant: xxx

a travaillé pour moi.


1 commentaires

J'ai déjà défini PictureFormat vers JPEG, et je ne peux pas me voir demander à chaque utilisateur de désir de mettre à jour leur téléphone. Mais merci pour l'info