ビットマップのサイズを正確に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;
}
私にぴったりの答えが見つかりました:
/**
* 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
はビットマップです
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();
}
}