如何在保存前压缩图片以提升RecyclerView的加载/显示速度?
解决方案:拍摄时直接压缩图片或低质量保存
完全可以在你当前的代码流程中实现图片压缩需求,以下是两种实用方案:
方法一:通过CameraX配置直接生成低质量图片
这是效率最高的方式,无需额外的后期处理开销。在初始化ImageCapture实例时,直接设置JPEG质量参数,让CameraX拍摄时就生成压缩后的图片:
// 初始化ImageCapture时添加压缩配置 ImageCapture imageCapture = new ImageCapture.Builder() .setJpegQuality(50) // 设置JPEG质量(范围0-100,值越小压缩率越高、文件体积越小) .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) // 优先降低延迟,适配快速拍摄场景 .build();
你可以根据实际需求调整setJpegQuality的数值(比如30-60之间测试),找到画质和文件大小的平衡点。
方法二:拍摄后对图片进行尺寸+质量双重压缩
如果需要精确控制图片的分辨率(比如固定宽度800px),可以在图片保存完成后,在onImageSaved回调中进行二次压缩处理:
修改你的onImageSaved逻辑,并新增压缩工具方法:
@Override public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) { new Handler(Looper.getMainLooper()).post(() -> { // 先执行图片压缩 compressImage(file, 800, 600, 50); // 目标宽度、高度、压缩质量 Uri uri = Uri.fromFile(file); ImageView preview = TrackFragment.getImageViewInTrackFragment(); preview.setImageURI(uri); TrackFragment.setImgPreviewUri(uri); Toast.makeText(CameraActivity.this, "图片已保存并压缩", Toast.LENGTH_SHORT).show(); CameraActivity.this.finish(); }); } // 图片压缩工具方法:调整尺寸+质量压缩 private void compressImage(File originalFile, int targetWidth, int targetHeight, int quality) { try { // 先获取原始图片的尺寸信息,不加载完整图片到内存 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(originalFile.getAbsolutePath(), options); // 计算合适的采样率,缩小图片尺寸 options.inSampleSize = calculateInSampleSize(options, targetWidth, targetHeight); options.inJustDecodeBounds = false; // 加载缩小后的图片并压缩保存 Bitmap bitmap = BitmapFactory.decodeFile(originalFile.getAbsolutePath(), options); FileOutputStream fos = new FileOutputStream(originalFile); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos); // 释放资源 fos.flush(); fos.close(); bitmap.recycle(); } catch (IOException e) { e.printStackTrace(); } } // 计算采样率的辅助方法 private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 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; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
注意事项
- 优先选择方法一,因为它直接由CameraX底层处理压缩,避免了额外的内存占用和CPU开销。
- 方法二更适合需要精确控制图片分辨率的场景,但要注意及时释放Bitmap资源,避免内存泄漏。
- 测试不同的质量值和尺寸参数,确保图片满足显示需求的同时,尽可能减小文件体积,从而提升RecyclerView的加载速度。
内容的提问来源于stack exchange,提问作者J_R
相关产品推荐
相关产品推荐

