33

ビットマップのサイズを正確に 200kb に減らしたい。SDカードから画像を取得し、圧縮して、別の名前で別のディレクトリに再度SDカードに保存します。圧縮は正常に機能します (3 mb のような画像は約 100 kb に圧縮されます)。このために次のコード行を書きました。

String imagefile ="/sdcard/DCIM/100ANDRO/DSC_0530.jpg";
Bitmap bm = ShrinkBitmap(imagefile, 300, 300);

//this method compresses the image and saves into a location in sdcard
    Bitmap ShrinkBitmap(String file, int width, int height){

         BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

            int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
            int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);

            if (heightRatio > 1 || widthRatio > 1)
            {
             if (heightRatio > widthRatio)
             {
              bmpFactoryOptions.inSampleSize = heightRatio;
             } else {
              bmpFactoryOptions.inSampleSize = widthRatio; 
             }
            }

            bmpFactoryOptions.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

            ByteArrayOutputStream stream = new ByteArrayOutputStream();   
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);   
            byte[] imageInByte = stream.toByteArray(); 
            //this gives the size of the compressed image in kb
            long lengthbmp = imageInByte.length / 1024; 

            try {
                bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream("/sdcard/mediaAppPhotos/compressed_new.jpg"));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


         return bitmap;
        }
4

3 に答える 3

69

私にとって完璧に機能する答えを見つけました:

/**
 * reduces the size of the image
 * @param image
 * @param maxSize
 * @return
 */
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
    int width = image.getWidth();
    int height = image.getHeight();

    float bitmapRatio = (float)width / (float) height;
    if (bitmapRatio > 1) {
        width = maxSize;
        height = (int) (width / bitmapRatio);
    } else {
        height = maxSize;
        width = (int) (height * bitmapRatio);
    }
    return Bitmap.createScaledBitmap(image, width, height, true);
}

メソッドの呼び出し:

Bitmap converetdImage = getResizedBitmap(photo, 500);

photoビットマップはどこにありますか

于 2014-08-05T10:27:15.050 に答える
10

widthと を変更せずに画質を制限するソリューションを次に示しますheight。このアプローチの主なアイデアは、出力サイズが より大きい場合に、ループ内でビットマップを圧縮することですmaxSizeBytesCount答えはこの質問に感謝します。このコード ブロックは、画質を下げるロジックのみを示しています。

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        int currSize;
        int currQuality = 100;

        do {
            bitmap.compress(Bitmap.CompressFormat.JPEG, currQuality, stream);
            currSize = stream.toByteArray().length;
            // limit quality by 5 percent every time
            currQuality -= 5;

        } while (currSize >= maxSizeBytes);

完全な方法は次のとおりです。

public class ImageUtils {

    public byte[] compressBitmap(
            String file, 
            int width, 
            int height,
            int maxSizeBytes
    ) {
        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
        bmpFactoryOptions.inJustDecodeBounds = true;
        Bitmap bitmap;

        int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
        int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);

        if (heightRatio > 1 || widthRatio > 1)
        {
            if (heightRatio > widthRatio)
            {
                bmpFactoryOptions.inSampleSize = heightRatio;
            } else {
                bmpFactoryOptions.inSampleSize = widthRatio;
            }
        }

        bmpFactoryOptions.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        int currSize;
        int currQuality = 100;

        do {
            bitmap.compress(Bitmap.CompressFormat.JPEG, currQuality, stream);
            currSize = stream.toByteArray().length;
            // limit quality by 5 percent every time
            currQuality -= 5;

        } while (currSize >= maxSizeBytes);

        return stream.toByteArray();
    }
}
于 2019-06-02T07:05:41.923 に答える
0

@TharakaNirmana によるメソッドは正常に機能し、maxSize はキロバイト単位です

例:

fun getResizedBitmap(image: Bitmap, maxSize: Int): Bitmap? {
    var width = image.width
    var height = image.height
    val bitmapRatio = width.toFloat() / height.toFloat()
    if (bitmapRatio > 1) {
        width = maxSize
        height = (width / bitmapRatio).toInt()
    } else {
        height = maxSize
        width = (height * bitmapRatio).toInt()
    }
    return Bitmap.createScaledBitmap(image, width, height, true)
}

使用法:

bitmap.let {
    val data = it.value

    if (data != null) {

        var image = viewModel.getResizedBitmap(data, 170)
        Log.d ("bitmap size", image!!.byteCount.toString()) ...

答え

2021-12-18 12:38:11.218 25502-25502/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 67200 2021-12-18 12:39:11.673 25745-25745/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 67200 2021-12-18 12:39:14.511 25745-25745/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 90000 2021-12-18 12:39:20.423 25745-25745/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 67200 2021-12-18 12:39:40.112 25907-25907/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 120000 2021-12-18 12:39:43.322 25907-25907/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 12000 2021-12-18 12:39:47.314 25907-25907/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 160000 2021-12-18 12:40:17.231 26069-26069/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 11560 2021-12-18 12:40:19.583 26069-26069/com.jdsalasc.sophosSolutions D/ビットマップ サイズ: 86360

ご覧のとおり、バイトサイズが 150 kb を超えることはありません

Zoe と TharakaNirmana に感謝します c:

于 2021-12-18T17:50:55.660 に答える