缩放位图保持纵横比

新手上路,请多包涵

我想将 Bitmap 缩放到与运行时相关的宽度和高度,其中保持纵横比并且 Bitmap 填充整个宽度并将图像垂直居中,或者裁剪多余的或用 0 alpha 像素填充间隙。

我目前正在自己重绘位图,方法是创建所有 0 alpha 像素的 Bitmap 并在其上绘制图像 Bitmap ,缩放到精确的指定宽度并保持纵横比,但是,它最终会丢失/弄乱像素数据。

这是我的做法:

 Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888);
float originalWidth = originalImage.getWidth(), originalHeight = originalImage.getHeight();
Canvas canvas = new Canvas(background);
float scale = width/originalWidth;
float xTranslation = 0.0f, yTranslation = (height - originalHeight * scale)/2.0f;
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
canvas.drawBitmap(originalImage, transformation, null);
return background;

是否有一个库或一些更好的代码可以更好地做到这一点?我希望图像看起来尽可能清晰,但我知道我的函数不会提供很好的结果。

我知道我可以通过使用整数缩放而不是浮点缩放来使图像保持正常,但我需要 100% 填充宽度。

另外,我知道 ImageViewGravity.CENTER_CROP 功能,但是,它也使用整数缩放,因此它会在不应该的时候切断图像的宽度。

原文由 RileyE 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 404
2 个回答

那这个呢:

 Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888);

float originalWidth = originalImage.getWidth();
float originalHeight = originalImage.getHeight();

Canvas canvas = new Canvas(background);

float scale = width / originalWidth;

float xTranslation = 0.0f;
float yTranslation = (height - originalHeight * scale) / 2.0f;

Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);

Paint paint = new Paint();
paint.setFilterBitmap(true);

canvas.drawBitmap(originalImage, transformation, paint);

return background;

我添加了一个 paint 来过滤缩放位图。

原文由 Streets Of Boston 发布,翻译遵循 CC BY-SA 3.0 许可协议

Kotlin 扩展功能版本基于 joaomgcd 的回答

private fun Bitmap.resize(maxWidth: Int, maxHeight: Int): Bitmap {
    return if (maxHeight > 0 && maxWidth > 0) {
        val width = this.width
        val height = this.height
        val ratioBitmap = width.toFloat() / height.toFloat()
        val ratioMax = maxWidth.toFloat() / maxHeight.toFloat()
        var finalWidth = maxWidth
        var finalHeight = maxHeight
        if (ratioMax > ratioBitmap) {
            finalWidth = (maxHeight.toFloat() * ratioBitmap).toInt()
        } else {
            finalHeight = (maxWidth.toFloat() / ratioBitmap).toInt()
        }
        Bitmap.createScaledBitmap(this, finalWidth, finalHeight, true)
    } else this
}

原文由 Vahid 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题