3 votes

Bitmaps en niveaux de gris dans Android

J'ai un tableau d'octets qui correspond à un "bitmap à échelle de gris" (un octet->un pixel), et je dois créer un fichier PNG pour cette image.

La méthode ci-dessous fonctionne, mais le png créé est ENORME, car le bitmap que j'utilise est un bitmap ARGB_8888, qui prend 4 octets par pixel au lieu de 1 octet.

Je n'ai pas réussi à le faire fonctionner avec d'autres Bitmap.Config différents de ARGB_8888. Peut-être qu'ALPHA_8 est ce dont j'ai besoin, mais je n'ai pas réussi à le faire fonctionner.

J'ai également essayé la méthode toGrayScale qui est incluse dans d'autres messages ( Convertir un bitmap en échelle de gris dans Android ), mais j'ai le même problème avec la taille.

public static boolean createPNGFromGrayScaledBytes(ByteBuffer grayBytes, int width,
        int height,File pngFile) throws IOException{

    if (grayBytes.remaining()!=width*height){
        Logger.error(Tag, "Unexpected error: size mismatch [remaining:"+grayBytes.remaining()+"][width:"+width+"][height:"+height+"]", null);
        return false;
    }
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    // for each byte, I set it in three color channels.
    int gray,color;
    int x=0,y=0;        
    while(grayBytes.remaining()>0){

        gray = grayBytes.get();
        // integer may be negative as byte is signed. make them positive. 
        if (gray<0){gray+=256;}

        // for each byte, I set it in three color channels.
        color= Color.argb(-1, gray, gray, gray);

        bitmap.setPixel(x, y, color);
        x++;
        if (x==width){
            x=0;
            y++;
        }           
    }
    FileOutputStream fos=null;

    fos = new FileOutputStream(pngFile);
    boolean result= bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
    fos.close();
    return result;
}       

EDIT : Lien vers le fichier généré (il peut sembler absurde, mais il est juste créé avec des données aléatoires). http://www.tempfiles.net/download/201208/256402/huge_png.html

Toute aide sera grandement appréciée.

5voto

Error 454 Points 4121

Comme vous l'avez remarqué, l'enregistrement d'une image en niveaux de gris en tant que RVB est coûteux. Si vous disposez de données de luminance, il est préférable d'enregistrer une image en niveaux de gris au format PNG plutôt qu'au format RVB.

La fonctionnalité bitmap et image disponible dans le cadre Android est vraiment orientée vers la lecture et l'écriture des formats d'image qui sont pris en charge par le cadre et les composants de l'interface utilisateur. Les PNG en niveaux de gris ne sont pas inclus ici.

Si vous souhaitez enregistrer un PNG en niveaux de gris sur Android, vous devez utiliser une bibliothèque comme la suivante http://code.google.com/p/pngj/

2voto

user1914692 Points 578

Si vous utilisez la bibliothèque OPENCV pour Android, vous pouvez utiliser la bibliothèque pour enregistrer des données binaires dans un fichier png. Ma méthode est la suivante : dans la partie jni, définir Mat dont les données commencent par le tableau d'octets :

jbyte* _ByteArray_BrightnessImgForOCR = env->GetByteArrayElements(ByteArray_BrightnessImgForOCR, 0);
Mat img(ByteArray_BrightnessImgForOCR_h, ByteArray_BrightnessImgForOCR_w, CV_8UC1, (unsigned char *) _ByteArray_BrightnessImgForOCR);

Et ensuite l'écrire dans un fichier png.

imwrite("/mnt/sdcard/binaryImg_forOCR.png", img);

Bien entendu, vous devez prendre le temps de vous familiariser avec OpenCV et le codage natif Java. En suivant Exemples d'OpenCV pour Android il est rapide à apprendre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X