【问题标题】:Android compress image with small size and good quality from camera intentAndroid从相机意图中压缩尺寸小且质量好的图像
【发布时间】:2021-06-25 05:20:29
【问题描述】:

在我的应用程序中,用户可以从相机意图中拍照,然后我将此图像保存为全尺寸图像 不是缩略图。然后我要做的是使用这个保存的图像来压缩它并将它发送到服务器。

相机意图的图像大小约为 7-8 MB,分辨率为 5664x4248。

要求是达到whatsapp的相同大小和质量的图像为40-80KB

我尝试了不同的解决方案,但无法达到同样好的质量和尺寸。

为此,我使用了id.zelory:compressor:2.1.1

有什么想法吗?

这里我保存图片后调用这个方法来调整大小

private File customCompressImage (File imgFile) {
    String destinationDirectoryPath=  Environment.getExternalStorageDirectory().getPath() + "/Pictures/";
    try {
        return new CustomCompressor(context)
                 .setMaxWidth(612)
                 .setMaxHeight(816)
                 .setQuality(80)
                 .setCompressFormat(Bitmap.CompressFormat.JPEG)
                 .setDestinationDirectoryPath(destinationDirectoryPath)
                 .compressToFile(imgFile);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

压缩图像

static File compressImage(File imageFile, int reqWidth, int reqHeight, Bitmap.CompressFormat compressFormat, int quality, String destinationPath) throws IOException {
    FileOutputStream fileOutputStream = null;
    File file = new File(destinationPath).getParentFile();
    if (!file.exists()) {
        file.mkdirs();
    }
    try {
        fileOutputStream = new FileOutputStream(destinationPath);
        // write the compressed bitmap at the destination specified by destinationPath.
        decodeSampledBitmapFromFile(imageFile, reqWidth, reqHeight).compress(compressFormat, quality, fileOutputStream);
    } finally {
        if (fileOutputStream != null) {
            fileOutputStream.flush();
            fileOutputStream.close();
        }
    }

    return new File(destinationPath);
}


static Bitmap decodeSampledBitmapFromFile(File imageFile, int reqWidth, int reqHeight) throws IOException {
    // First decode with inJustDecodeBounds=true to check dimensions
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    Bitmap scaledBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);

    //check the rotation of the image and display it properly
    ExifInterface exif;
    exif = new ExifInterface(imageFile.getAbsolutePath());
    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
    Matrix matrix = new Matrix();
    if (orientation == 6) {
        matrix.postRotate(90);
    } else if (orientation == 3) {
        matrix.postRotate(180);
    } else if (orientation == 8) {
        matrix.postRotate(270);
    }
    scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
    return scaledBitmap;
}


private 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;
}

我尝试传递不同的最大宽度和高度以及质量,但我从未同时实现小尺寸和高质量

【问题讨论】:

  • 调整大小的图像应该有什么分辨率? 5664x4248 --> wxh?当然,如果您调整大小,质量会降低。
  • 更多位图现在可以压缩为 .webp,在相同质量下缩小 30%。

标签: java android file-upload compression image-compression


【解决方案1】:

你可以试试这段代码。

public static Bitmap getCompressed( Bitmap imageBitmap) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    return imageBitmap;
}

// 100 是质量, 根据你的需要改变它

【讨论】:

  • 请查看我的解决方案,因为我认为您的解决方案在将压缩图像写入 OutputStream 后不会对其进行任何处理。根据developer.android.com/reference/android/graphics/…Bitmap.compress 不压缩bitmap compress 被调用,而是将压缩版本写入OutputStream,你的版本没有使用
  • 代码是给出需要做的事情,我认为用户可以从这里提前跟进。
  • 没有什么可跟进的,因为 OP 已经使用了 Bitmap.compress()。
【解决方案2】:

@End User 不应该是这样吗(至少我从阅读文档中得到了):

public static Bitmap getCompressed(Bitmap imageBitmap) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    if (!imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out))
        throw new IllegalStateException("Unable to compress image");
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    return BitmapFactory.decodeStream(in);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2018-11-09
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    相关资源
    最近更新 更多