Development Tip

Android-이미지 파일 크기 줄이기

yourdevel 2020. 12. 31. 23:03
반응형

Android-이미지 파일 크기 줄이기


URI 이미지 파일이 있는데 업로드 할 크기를 줄이고 싶습니다. 초기 이미지 파일 크기는 모바일에 따라 다르지만 (2MB가 될 수 있고 500KB가 될 수 있음) 최종 크기가 약 200KB가되어야 업로드 할 수 있습니다.
내가 읽은 내용에서 (적어도) 두 가지 선택이 있습니다.

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

더 나은 방법이 있습니까? 두 가지 방법을 모두 계속 사용해야합니까, 아니면 하나만 사용해야합니까? 감사


사용하여 Bitmap.compress()방금 압축 알고리즘을 지정하는 방식의 압축 작업에 의해하는 것은 시간이 아니라 큰 금액을합니다. 이미지에 대한 메모리 할당을 줄이기 위해 크기를 조정해야하는 경우를 사용하여 이미지 크기 조정을 사용 Bitmap.Options하고 처음에는 비트 맵 경계를 계산 한 다음 지정된 크기로 디코딩해야합니다.

내가 StackOverflow에서 찾은 최고의 샘플은 이것 입니다.


내가 찾은 대부분의 답변 은 아래에 게시작업 코드 를 얻기 위해 함께 모아야하는 부분 일뿐입니다.

 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 is used to subsample the original image and return a smaller image, ie
SampleSize == 4 returns an image that is 1/4 the width/height of the original.

quality is used to hint the compressor, input range is between 0-100. 0 meaning compress for small size, 100 meaning compress for max quality


BitmapFactory.Options - Reduces Image Size (In Memory)

Bitmap.compress() - Reduces Image Size (In Disk)


Refer to this link for more information about using both of them: https://android.jlelse.eu/loading-large-bitmaps-efficiently-in-android-66826cd4ad53

ReferenceURL : https://stackoverflow.com/questions/11061280/android-reduce-image-file-size

반응형