2
votes

Android, comment réduire la taille d'un bitmap?

J'ai une application qui permet à l'utilisateur de changer l'image de son profil en une autre qui est stockée sur son appareil. Pour cela, l'application envoie l'image sélectionnée à un serveur distant. Tout cela fonctionne bien, donc je ne mets pas le code de cette partie pour ne pas compliquer la question. Mon problème est que je veux que le bitmap envoyé au serveur soit réduit en taille pour éviter, par exemple, les gros fichiers de cinq ou six mégaoctets, qui ralentissent l'application. Mais ça ne se termine pas bien.

Voici mon code pour ça:

if (requestCode == 1 && resultCode == RESULT_OK) {

            Uri selectedImageUri = data.getData();
            imagepath = getPath(selectedImageUri);
            Bitmap bitmap=BitmapFactory.decodeFile(imagepath);

            ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();

            //Resize the bitmap
            Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 150, 150, false);

            resizedBitmap.compress(Bitmap.CompressFormat.JPEG,50,bytearrayoutputstream);


            //Round the image
            int min = Math.min(resizedBitmap.getWidth(), resizedBitmap.getHeight());

            Bitmap bitmapRounded = Bitmap.createBitmap(min, min, resizedBitmap.getConfig());

            Canvas canvas = new Canvas(bitmapRounded);
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setShader(new BitmapShader(resizedBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
            canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min / 2, min / 2, paint);

            //bitmap to imageView
            avatar.setImageBitmap(bitmapRounded);

}

J'essaye de le réduire en taille (ça ne marche pas) puis j'arrondis l'image (cela fonctionne bien) avant de l'ajuster à l'ImageView correspondante.

La seule chose que je n'arrive pas à faire fonctionner correctement est de réduire la taille du bitmap.


0 commentaires

4 Réponses :


1
votes

J'utilise ceci pour réduire ma taille de bitmap et cela fonctionne bien: -

ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, baos);


0 commentaires

0
votes

Si vous souhaitez réduire la taille de votre image, vous devez d'abord obtenir la hauteur et la largeur de votre bitmap, calculer le rapport, puis créer une image à l'échelle.

int width = image.getWidth();
int height = image.getHeight();

Vous devez calculer la taille de l'image et renvoyer le bitmap mis à l'échelle.

Trouvez une question similaire posée ici: Réduisez la taille d'un bitmap à une taille spécifiée sous Android

J'espère que vous obtiendrez la solution exacte. p>


0 commentaires

0
votes

Essayez ceci:

ByteArrayOutputStream ostream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 80, ostream);


1 commentaires

Malheureusement, cette solution présente certaines limites. Si la source est un fichier PNG, il ne fait rien du tout. De plus, si le CompressFormat est défini sur PNG, la compression ne fera rien au bitmap



0
votes

J'utilise cette classe d'assistance.

public class ScaleFile {
    private Context mContext;

    public ScaleFile(Context context) {
        this.mContext = context;
    }

    public Bitmap scaleFile(String imageUri) {

        String filePath = getRealPathFromURI(imageUri);
        Bitmap scaledBitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();


        options.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;

         //max Height and width values of the compressed image is taken as 816x612

        float maxHeight = 816.0f;
        float maxWidth = 612.0f;
        float imgRatio = actualWidth / actualHeight;
        float maxRatio = maxWidth / maxHeight;

        //width and height values are set maintaining the aspect ratio of the image

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }

    //setting inSampleSize value allows to load a scaled down version of the original image

        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);


        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {
            //load the bitmap from its path
            bmp = BitmapFactory.decodeFile(filePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();

        }
        try {
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

         // check the rotation of the image and display it properly
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);

            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
            } else if (orientation == 3) {
                matrix.postRotate(180);
            } else if (orientation == 8) {
                matrix.postRotate(270);
            }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(),
                    scaledBitmap.getHeight(), matrix, true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return scaledBitmap;
    }

    private String getRealPathFromURI(String contentURI) {
        Uri contentUri = Uri.parse(contentURI);
        Cursor cursor = mContext.getContentResolver().query(contentUri, null, null, null, null);
        if (cursor == null) {
            return contentUri.getPath();
        } else {
            cursor.moveToFirst();
            int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            return cursor.getString(index);
        }
    }

    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        final float totalPixels = width * height;
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;
        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }

        return inSampleSize;
    }

}


0 commentaires