
IM即时通讯
安全可靠、全球互通

实时音视频
流畅稳定、省钱省力
回答:
原图宽或高只要有一边大于 240 则执行压缩处理
根据缩率图最大尺寸 240、最小尺寸 100 的要求加载图片文件(适度同比缩放原图)
将步骤 2 得到的图片按照原图 30% 的比例进行容量压缩
private static final int THUMB_COMPRESSED_SIZE = 240; private static final int THUMB_COMPRESSED_MIN_SIZE = 100; private static final int THUMB_COMPRESSED_QUALITY = 30; ImageMessage model = ...; // 图片消息 String thumbPath = model.getThumUri().toString().substring(5); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(thumbPath, options); String imageFormat = options.outMimeType != null ? options.outMimeType : ""; // 1. 原图宽或高只要有一边大于 240 则执行压缩处理 if (options.outWidth > THUMB_COMPRESSED_SIZE || options.outHeight > THUMB_COMPRESSED_SIZE) { // 2. 根据缩率图最大尺寸 240、最小尺寸 100 的要求加载图片文件(适度同比缩放原图) Bitmap bitmap = getThumbBitmap(getContext(), model.getThumUri(), THUMB_COMPRESSED_SIZE, THUMB_COMPRESSED_MIN_SIZE); if (bitmap != null) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 3. 将步骤 2 得到的图片按照原图 30% 的比例进行容量压缩 boolean success = bitmap.compress(Bitmap.CompressFormat.JPEG, THUMB_COMPRESSED_QUALITY, outputStream); // 在部分机型调用系统压缩转换png会有异常情况,修改后先进行判断是否压缩成功,如果压缩不成功则使用png方式进行二次压缩 if (!success) { bitmap.compress(Bitmap.CompressFormat.PNG, THUMB_COMPRESSED_QUALITY, outputStream); } model.setBase64(Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP)); outputStream.close(); model.setThumUri(Uri.parse("file://" + uri.toString() + IMAGE_THUMBNAIL_PATH + name)); if (!bitmap.isRecycled()) bitmap.recycle(); } }
public static Bitmap getThumbBitmap(Context context, @NonNull Uri uri, int sizeLimit, int minSize) throws IOException { String path; Bitmap result; if (("file").equals(uri.getScheme())) { path = uri.toString().substring(5); } else if (("content").equals(uri.getScheme())) { Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null); if (cursor == null) { return null; } cursor.moveToFirst(); path = cursor.getString(0); cursor.close(); } else { return null; } ExifInterface exifInterface = new ExifInterface(path); Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); int width = options.outWidth; int height = options.outHeight; int longSide = (width > height) ? width : height; int shortSide = (width > height) ? height : width; float scale = (float) longSide / shortSide; int sampleW = 1, sampleH = 1; int sampleSize = 1; if (scale > (float) sizeLimit / minSize) { while (shortSide / 2 > minSize) { shortSide /= 2; sampleSize <<= 1; } options = new Options(); options.inSampleSize = sampleSize; } else { while (width / 2 > sizeLimit) { width /= 2; sampleW <<= 1; } while (height / 2 > sizeLimit) { height /= 2; sampleH <<= 1; } options = new Options(); sampleSize = Math.max(sampleW, sampleH); options.inSampleSize = sampleSize; } Bitmap bitmap; try { bitmap = BitmapFactory.decodeFile(path, options); } catch (OutOfMemoryError e) { options.inSampleSize = options.inSampleSize << 1; bitmap = BitmapFactory.decodeFile(path, options); } Matrix matrix = new Matrix(); if (bitmap == null) { return null; } int w = bitmap.getWidth(); int h = bitmap.getHeight(); if (orientation == ExifInterface.ORIENTATION_ROTATE_90 || orientation == ExifInterface.ORIENTATION_ROTATE_270 || orientation == ExifInterface.ORIENTATION_TRANSPOSE || orientation == ExifInterface.ORIENTATION_TRANSVERSE) { int tmp = w; w = h; h = tmp; } switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: matrix.setRotate(90, w / 2f, h / 2f); break; case ExifInterface.ORIENTATION_ROTATE_180: matrix.setRotate(180, w / 2f, h / 2f); break; case ExifInterface.ORIENTATION_ROTATE_270: matrix.setRotate(270, w / 2f, h / 2f); break; case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: matrix.preScale(-1, 1); break; case ExifInterface.ORIENTATION_FLIP_VERTICAL: matrix.preScale(1, -1); break; case ExifInterface.ORIENTATION_TRANSPOSE: matrix.setRotate(90, w / 2f, h / 2f); matrix.preScale(1, -1); break; case ExifInterface.ORIENTATION_TRANSVERSE: matrix.setRotate(270, w / 2f, h / 2f); matrix.preScale(1, -1); break; } float sS = 0; float xS = 0; float yS = 0; if (scale > (float) sizeLimit / minSize) { shortSide = (bitmap.getWidth() > bitmap.getHeight()) ? bitmap.getHeight() : bitmap.getWidth(); sS = (float) minSize / shortSide; matrix.postScale(sS, sS); } else { xS = (float) sizeLimit / bitmap.getWidth(); yS = (float) sizeLimit / bitmap.getHeight(); matrix.postScale(Math.min(xS, yS), Math.min(xS, yS)); } int x = 0, y = 0; try { if (scale > (float) sizeLimit / minSize) { if (bitmap.getWidth() > bitmap.getHeight()) { h = bitmap.getHeight(); w = h * sizeLimit / minSize; x = (bitmap.getWidth() - w) / 2; y = 0; } else { w = bitmap.getWidth(); h = w * sizeLimit / minSize; x = 0; y = (bitmap.getHeight() - h) / 2; } } else { w = bitmap.getWidth(); h = bitmap.getHeight(); } result = Bitmap.createBitmap(bitmap, x, y, w, h, matrix, true); } catch (OutOfMemoryError e) { if (!bitmap.isRecycled()) bitmap.recycle(); return null; } if (!bitmap.isRecycled() && !bitmap.equals(result)) bitmap.recycle(); return result; }
注意:以上示例代码为 Android 端实现,且使用了 Android 平台图片处理相关 API