如果照片太大(例如宽度> 2048像素),我想调整每张用相机拍摄的照片。
我在官方文件中看到了
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
和
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
但是这段代码涉及我知道最终的大小。 我想要做的是如果它真的太大则减少50%,或者如果位图不是太大则减少20%等等(取决于智能手机的相机......)
方法calculateInSampleSize()似乎做了我想做的事,文档说"例如,使用inSampleSize为4解码的分辨率为2048x1536的图像产生大约512x384"的位图。但我不想设置最终的宽度/高度。
然后,当我得到较小的位图时,我想制作一个
scaledBitmap.compress(CompressFormat.JPEG, 80, out);
再次优化。
我该如何解决这个问题?
答案 0 :(得分:0)
您可以将位图的宽度和高度设为bitmap.getWidth()
和bitmap.getHeight()
。一旦你有宽度和高度,检查哪个值更小。如果width小于height,请将width
存储在一个名为value
的变量中,否则存储height
。
然后您可以通过检查值来压缩位图,如下所示。
Bitmap bitmap = your bitmap;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int value;
if (width < height) {
value = width;
} else {
value = height;
}
Bitmap scaledBitmap;
if (value > 5000) {
scaledBitmap = bitmap.compress(CompressFormat.JPEG, 80, out);
} else if (value > 4000) {
scaledBitmap = bitmap.compress(CompressFormat.JPEG, 60, out);
} else if (value > 3000) {
scaledBitmap = bitmap.compress(CompressFormat.JPEG, 40, out);
} else if (value > 2048) {
scaledBitmap = bitmap.compress(CompressFormat.JPEG, 20, out);
}
答案 1 :(得分:0)
最后我选择了另一种解决方案:
public static void resizeBitmapOnFileSystem(String originalPath, File photoCompressedFile) throws IOException {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(originalPath, options);
int minimalLengthSide = 300; //Minimal length of the shorter side of the picture. Used to calculate the best 'scale' value.
int scale = calculateInSampleSize(options, minimalLengthSide, minimalLengthSide);
ByteArrayOutputStream out = null;
FileOutputStream fo = null;
Bitmap scaledBitmap = null;
try {
out = new ByteArrayOutputStream();
fo = new FileOutputStream(photoCompressedFile);
scaledBitmap = loadScaledBitmap(originalPath, scale);
if (scaledBitmap != null) {
scaledBitmap.compress(CompressFormat.JPEG, 75, out);
fo.write(out.toByteArray());
}
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(fo);
recycleQuietly(scaledBitmap);
}
}
/**
* From offical Android documentation
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
即使resizeBitmapOnFileSystem()
方法不是很“方便”,诀窍就是minimalLengthSide
变量。我设置了我想要的短边的最小长度(这里是300px),方法calculateInSampleSize()
将自动计算出适当的比例。
保持比率宽度/高度,我不使用
Bitmap.createScaledBitmap(realImage, width, height, filter)
这可能是“代价高昂”或效率低下。