上传到服务器上的图片,要求不能太大,而且要相对清晰。
采用策略:
- 先图片尺寸压缩,宽满足小于 960 or 高小于1200
- 再按照大小进行压缩,小于60KB
具体代码:
public static void scaleImageFile(String path) {
File file = new File(path);
File tmpFile = new File(path + ".tmp");
if (!tmpFile.exists()) {
try {
tmpFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Bitmap bmp = ImageUtils.scaleImage(path, 480, 600);
if (bmp == null)
return;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 100;//
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
// 如果大于1M,先压缩50%,减少bmp.compress的调用次数(非常耗时)
if (baos.toByteArray().length / 1024 > 1024) {
baos.reset();
options -= 50;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
// 如果还没有达到要求,继续压缩
while (baos.toByteArray().length / 1024 > 60) {
baos.reset();
options -= 20;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
这里面引用了一个方法scaleImage,是按照480*600对图片进行压缩。
public static Bitmap scaleImage(String imagePath, int width, int height) {
try {
if (imagePath == null)
return null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
int digree = getRotateDigree(imagePath);
if (digree == 90 || digree == 270) { // 宽高交换
options.inSampleSize = calculateInSampleSize(options, height,
width);
} else {
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, width,
height);
}
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
if ("PRO 5".equals(CldModeUtils.getMobileModel())) {
try {
bmp = BitmapFactory.decodeStream(
HFModesManager.getContext().getContentResolver()
.openInputStream(Uri.parse(imagePath)),
null, options);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return rotateBitmap(digree, bmp);
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
里面用到2个方法:一个是计算采样率 第二个是旋转图片
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;
}
private static Bitmap rotateBitmap(int digree, Bitmap bmp) {
Bitmap rotateBmp = null;
if (digree != 0) {
try {
// 旋转图片
Matrix m = new Matrix();
m.postRotate(digree);
rotateBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), m, true);
bmp.recycle();
} catch (OutOfMemoryError e) { // 出现内存溢出则使用原图片
rotateBmp = bmp;
}
} else {
rotateBmp = bmp;
}
return rotateBmp;
}
最终图片如下: