안드로이드 압축 이미지
BitmapFactory.compress()
방법을 사용하여 그림을 압축하고 구체적인 압축 조작을 살펴보았다.1. inSampleSize 매개 변수
BitmapFactory
에는 내부 클래스BitmapFactory.Options
가 있는데 그 중에서 options.inSampleSize
값이 >1일 경우 문서에 따라If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. (1 -> decodes full size; 2 -> decodes 1/4th size; 4 -> decode 1/16th size). Because you rarely need to show and have full size bitmap images on your phone. For manipulations smaller sizes are usually enough.
options.inSampleSize
는 2의 지수 밑으로 축소된 것이다.이렇게 하면 우리는 inSampleSize
의 값 설정에 의존하여 그림을 축소하여 불러올 수 있다. 그러면 일반적인 상황에서도 상술한 OOM
문제가 발생하지 않을 것이다.현재 문제는 inSampleSize
의 값을 어떻게 확정합니까?사진마다 크기를 줄이는 비율이 달라야 합니다!그러면 실행할 때 동적으로 확인해야 합니다.BitmapFactory.Options
에 다른 멤버inJustDecodeBounds
를 제공했다.2. inJustDecodeBounds 매개변수
BitmapFactory.Options option = new BitmapFactory.Options();
option.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcPath, option);
inJustDecodeBounds
true로 설정한 후decodeFile
는 공간을 분배하지 않지만 원시 그림의 길이와 너비, 즉opts.width
와opts.height
를 계산할 수 있다.이 두 개의 매개 변수가 있으면 일정한 알고리즘을 통과하면 적당한 inSampleSize
를 얻을 수 있다.3. 구체적인 실행
public static String compressImage(String srcPath) {
//1.
BitmapFactory.Options option = new BitmapFactory.Options();
option.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcPath, option);
int actualWidth = option.outWidth;
int actualHeight = option.outHeight;
//
int desiredHeight = 800;
int desiredWidth = 480;
//2. inJustDecodeBounds false
option.inJustDecodeBounds = false;
option.inSampleSize = findBestSampleSize(actualWidth, actualHeight,
desiredWidth, desiredHeight);// inSampleSize
//3. Bitmap
Bitmap tempBitmap = BitmapFactory.decodeFile(srcPath, option);
//4. ( , , )
ByteArrayOutputStream baos = new ByteArrayOutputStream();
tempBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//100 100% , 0% : baos
int options = 90;
// , 200kb,
while (baos.toByteArray().length / 1024 > 200) {
baos.reset();
tempBitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//
options -= 10;
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
//5. ,
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
File file = null;
try {
File dir = Constants.me().getExternalDir();
if (!dir.exists()) {
dir.mkdirs();
}
String filename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()) + ".jpeg";
file = new File(dir, filename);
fos = new FileOutputStream(file);
while ((len = isBm.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.flush();
} catch (IOException e) {
Log4a.e(e);
} finally {
if (isBm != null) {
try {
isBm.close();
} catch (IOException e) {
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
if (tempBitmap != null) {
tempBitmap.recycle();
}
}
return file == null ? srcPath : file.getAbsolutePath();
}
// inSampleSize
static int findBestSampleSize(int actualWidth, int actualHeight,
int desiredWidth, int desiredHeight) {
double wr = (double) actualWidth / desiredWidth;
double hr = (double) actualHeight / desiredHeight;
double ratio = Math.min(wr, hr);
float n = 1.0f;
// >2 *2
while ((n * 2) <= ratio) {
n *= 2;
}
return (int) n;
}
4. 비트맵이 차지하는 저장 크기와 메모리 크기의 차이는 이 링크가 예를 들어 차이점을 설명하는 한 마디로 비트맵이다.compress 방법은 확실히 그림을 압축할 수 있지만, 압축된 것은 저장 크기입니다. 만약 비트맵이 차지하는 메모리가 적다면, 불러오는 픽셀의 길이와 너비를 설정해야 합니다. (미리 보기 그림으로)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.