Android 如何避免图像失真?

How to avoid image from distort in Android?

我想在以 base64 格式发送到服务器时重复使用位图的大小。例如,原始图像大小为 1.2 MB,因此我必须将其调整为 50KB(服务器限制端)。 The way make image distort sometimes. I have read [1] and [2],但没有帮助。

问题是某些图像在调整大小后变形。

这是我的代码:

private String RescaleImage(String bitmap, int size) {
    try {
        if ((float) bitmap.getBytes().length / 1000 <= Constants.PROFILE_IMAGE_LIMITED_SIZE) {
            return bitmap;
        } else {
            //Rescale
            Log.d("msg", "rescale size : " + size);
            size -= 1;
            bitmap = BitmapBase64Util.encodeToBase64(Bitmap.createScaledBitmap(decodeBase64(bitmap), size, size, false));
            return RescaleImage(bitmap, size);
        }
    } catch (Exception e) {
        return bitmap;
    }
}

encodingToBase64:

public static String encodeToBase64(Bitmap image) {
    Log.d(TAG, "encoding image");

    String result = "";
    if (image != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();
        result = Base64.encodeToString(b, Base64.DEFAULT);

        Log.d(TAG, result);
        return result;
    }
    return result;
}

图像在调整大小之前被裁剪。裁剪后尺寸为 300 x 300

我的问题是:

如何将图片大小重用到50KB,保持比例不变,避免失真?

您在Bitmap.createScaledBitmap(decodeBase64(bitmap), size, size, false)中传递了相同的宽度和高度。除非您的位图是正方形,否则您必须指定正确的宽度和高度,否则您的图像会根据原始纵横比扭曲。我认为这样的事情会奏效:

Bitmap scaledBitmap = Bitmap.createScaledBitmap(decodeBase64(bitmap);
bitmap = BitmapBase64Util.encodeToBase64(scaledBitmap, scaledBitmap.getWidth(), size.getHeight(), false);

如果您需要压缩以减小大小,请使用此[编辑:您已完成]:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); 
byte[] byteArray = stream.toByteArray();

我更新了我的代码,它现在运行得更好了。

-- 已修复 --

我没有连续调整位图字符串的大小,而是使用调整大小之前使用的原始位图。

private String RescaleImage(String bitmap, Bitmap origin_bitmap, int size) {
    try {
        if ((float) bitmap.getBytes().length / 1000 <= Constants.PROFILE_IMAGE_LIMITED_SIZE) {
            return bitmap;
        } else {
            //Rescale
            Log.d("msg", "rescale size : " + size);
            size -= 1;
            bitmap = BitmapBase64Util.encodeToBase64(Bitmap.createScaledBitmap(origin_bitmap, size, size, false));
            return RescaleImage(bitmap, origin_bitmap, size);
        }
    } catch (Exception e) {
        return bitmap;
    }
}

此外,在解码时使用此代码以重用失真。 Bad image quality after resizing/scaling bitmap.

如果有更好的修复,欢迎随时改进