studio - poly pdf android




Android-Réduire la taille du fichier image (2)

En utilisant Bitmap.compress() vous spécifiez simplement l'algorithme de compression et, de plus, l'opération de compression prend assez de temps. Si vous devez jouer avec des tailles permettant de réduire l’allocation de mémoire pour votre image, vous devez utiliser la mise à l’échelle de votre image à l’aide de Bitmap.Options , en calculant d'abord les limites de l'image, puis en la décodant à la taille spécifiée.

Le meilleur échantillon que j'ai trouvé sur StackOverflow est celui-ci .

J'ai un fichier image URI et je souhaite réduire sa taille pour le télécharger. La taille initiale du fichier image dépend d'un mobile à l'autre (peut atteindre 2 Mo et 500 Ko), mais je souhaite une taille finale d'environ 200 Ko pour pouvoir la télécharger.
D'après ce que j'ai lu, j'ai (au moins) 2 choix:

  • Utilisation de BitmapFactory.Options.inSampleSize pour sous-échantillonner l'image d'origine et obtenir une image plus petite.
  • Utilisation de Bitmap.compress pour compresser l'image en spécifiant la qualité de la compression.

Quel est le meilleur choix?

Je pensais initialement redimensionner la largeur / hauteur de l'image jusqu'à ce que largeur ou hauteur dépasse 1000px (environ 1024x768 ou autres), puis compresser l'image avec une qualité décroissante jusqu'à ce que la taille du fichier dépasse 200Ko. Voici un exemple:

int MAX_IMAGE_SIZE = 200 * 1024; // max final file size
Bitmap bmpPic = BitmapFactory.decodeFile(fileUri.getPath());
if ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) {
    BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
    bmpOptions.inSampleSize = 1;
    while ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) {
        bmpOptions.inSampleSize++;
        bmpPic = BitmapFactory.decodeFile(fileUri.getPath(), bmpOptions);
    }
    Log.d(TAG, "Resize: " + bmpOptions.inSampleSize);
}
int compressQuality = 104; // quality decreasing by 5 every loop. (start from 99)
int streamLength = MAX_IMAGE_SIZE;
while (streamLength >= MAX_IMAGE_SIZE) {
    ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
    compressQuality -= 5;
    Log.d(TAG, "Quality: " + compressQuality);
    bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream);
    byte[] bmpPicByteArray = bmpStream.toByteArray();
    streamLength = bmpPicByteArray.length;
    Log.d(TAG, "Size: " + streamLength);
}
try {
    FileOutputStream bmpFile = new FileOutputStream(finalPath);
    bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpFile);
    bmpFile.flush();
    bmpFile.close();
} catch (Exception e) {
    Log.e(TAG, "Error on saving file");
}

Y a-t-il une meilleure façon de le faire? Devrais-je essayer de continuer à utiliser les 2 méthodes ou une seule? Merci


La plupart des réponses que j'ai trouvées n'étaient que des morceaux que je devais assembler pour obtenir un code fonctionnel, qui est affiché ci-dessous

 public void compressBitmap(File file, int sampleSize, int quality) {
        try {
           BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = sampleSize;
            FileInputStream inputStream = new FileInputStream(file);

            Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, options);
            inputStream.close();

            FileOutputStream outputStream = new FileOutputStream("location to save");
            selectedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.close();
            long lengthInKb = photo.length() / 1024; //in kb
            if (lengthInKb > SIZE_LIMIT) {
               compressBitmap(file, (sampleSize*2), (quality/4));
            }

            selectedBitmap.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2 paramètres sampleSize et la qualité joue un rôle important

sampleSize est utilisé pour sous-échantillonner l'image d'origine et renvoyer une image plus petite , c'est-à-dire
SampleSize == 4 renvoie une image représentant 1/4 de la largeur / hauteur de l'original.

la qualité est utilisée pour indiquer le compresseur , la plage d'entrée est comprise entre 0 et 100. 0 signifie compresser pour une petite taille, 100 signifie compresser pour une qualité maximale





image-resizing