60

URI画像ファイルがありますが、アップロードするためにサイズを小さくしたいと思います。初期の画像ファイルサイズはモバイルごとに異なりますが(500KBの場合は2MB)、アップロードできるように最終的なサイズは約200KBにします。
私が読んだものから、私には(少なくとも)2つの選択肢があります:

  • BitmapFactory.Options.inSampleSizeを使用して、元の画像をサブサンプリングし、より小さな画像を取得します。
  • Bitmap.compressを使用して、圧縮品質を指定して画像を圧縮します。

最良の選択は何ですか?


最初に画像の幅/高さを1000px(1024x768など)を超えるまでサイズ変更し、次にファイルサイズが200KBを超えるまで品質を下げて画像を圧縮することを考えていました。次に例を示します。

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");
}

それを行うためのより良い方法はありますか?2つの方法すべてを使い続けるべきですか、それとも1つだけを使い続けるべきですか?ありがとう

4

3 に答える 3

31

圧縮アルゴリズムをBitmap.compress()指定するだけで、圧縮操作にはかなりの時間がかかります。Bitmap.Options画像のメモリ割り当てを減らすためにサイズを試す必要がある場合は、最初にビットマップ境界を計算してから、指定したサイズにデコードすることを使用して、画像のスケーリングを正確に使用する必要があります。

StackOverflowで見つけた最高のサンプルはこれです。

于 2012-06-16T06:18:13.850 に答える
1

私が見つけた答えのほとんどは、動作するコードを取得するためにまとめなければならなかった断片でした。これは以下に掲載されています。

 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つのパラメータsampleSizeと品質が重要な役割を果たします

sampleSize、元の画像をサブサンプリングして小さい画像を返すために使用されます。つまり、
SampleSize == 4は、元の画像の幅/高さの1/4の画像を返します。

品質はコンプレッサーを示唆するために使用され、入力範囲は0〜100です。0は小さいサイズの圧縮を意味し、100は最大品質の圧縮を意味します

于 2016-11-04T09:42:57.593 に答える
0

BitmapFactory.Options-画像サイズを縮小します(メモリ内)

Bitmap.compress() -画像サイズを縮小します(ディスク内)


両方の使用の詳細については、次のリンクを参照してください: https ://android.jlelse.eu/loading-large-bitmaps-efficiently-in-android-66826cd4ad53

于 2019-08-20T19:12:03.340 に答える