不改变原始宽高比,将位图调整为512x512大小

3

我创建了一些位图,它们的尺寸不是固定的。有时是120x60,129x800,851x784等等,没有具体的值...... 我想将这些位图调整大小为512x512,但不改变原始图像的长宽比并且不裁剪。新的图像必须有512x512的画布,原始图像必须在中心位置而没有任何裁剪。

我使用以下函数调整我的位图大小,但效果非常糟糕,因为它同时适用于图像的X和Y轴。我不希望图像同时适应X和Y轴,只要适应其中一个轴并保持其长宽比即可。

 public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(
                bm, 0, 0, width, height, matrix, false);
        bm.recycle();
        return resizedBitmap;
    }

我拥有的是:

输入图像描述

我想要的是:

输入图像描述


所以你想要添加填充。在你的例子中,是右侧和左侧填充。当原始图像比高度更宽时,你需要添加顶部和底部填充。 - Perdi Estaquel
@J.A.P 很明显,Mahir在谈论像素长宽比而不是图像长宽比。 - Perdi Estaquel
我想将原始图像适配到512x512的空位图中,使其居中且没有任何裁剪。你可以从我在问题中添加的图片中理解。再次感谢。 - user8652379
不,从技术上讲不可能。中心只有1像素的线 :) - user8652379
你需要的是填充。scaleWidth和scaleHeight中的最小值是你的拉伸因子,计算剩余空间并将其用于填充以将位图居中到另一个位图中。请参见此处: https://adilatwork.blogspot.com/2012/10/android-how-to-add-padding-or-border-to.html - Ph1llip2
感谢大家的评论。@Poohl的回答解决了我的问题。你可以在评论中找到完美的输出。 - user8652379
2个回答

3

好的,你已经非常接近了。我现在无法测试,但基本上需要更改的是:

1)你需要将相同的比例应用于X和Y,因此你需要选择较小的一个(如果这不起作用,请尝试较大的一个)。

matrix.postScale(Math.min(scaleWidth, scaleHeight), Math.min(scaleWidth, scaleHeight));

2) 结果将会是一个位图,其中至少一边的大小为512像素,另一边则会更小。因此,您需要添加填充以适应该边到512像素(对于居中,左右/上下同等)。为了做到这一点,您需要创建一个所需尺寸的新位图:

Bitmap outputimage = Bitmap.createBitmap(512,512, Bitmap.Config.ARGB_8888);

最后,根据 resizedBitmap 的哪一边大小为512px,您需要将 resizedBitmap 绘制到 outputImage 中的正确位置。

Canvas can = new Canvas(outputimage);
can.drawBitmap(resizedBitmap, (512 - resizedBitmap.getWidth()) / 2, (512 - resizedBitmap.getHeight()) / 2, null);

请注意,512 - resizedBitmap.getWidth() 的结果为0 ,因此不需要在边缘添加正确大小的填充。

4) 现在返回outputImage


你是王者。问题解决了...我真的非常感激。这是新的和最终的输出 :) http://prntscr.com/lu8gz9 你真的是最棒的。我为了修复它已经工作了超过12个小时。 - user8652379
1
不用客气,感谢您将我的答案标记为解决方案。 - Poohl
@user8652379 你能分享最终代码或编辑此答案以包含最终代码吗? - CrackerKSR

1

以下是使用 Kotlin 简化后的代码,该代码使用矩阵同时进行缩放和平移操作,跳过了中间位图的步骤。

请注意,它还将新像素的背景颜色设置为白色,这是我在图像处理流程中所需的。如果您不需要它,请随意删除。

fun resizedBitmapWithPadding(bitmap: Bitmap, newWidth: Int, newHeight: Int) : Bitmap {
    val scale = min(newWidth.toFloat() / bitmap.width, newHeight.toFloat() / bitmap.height)
    val scaledWidth = scale * bitmap.width
    val scaledHeight = scale * bitmap.height

    val matrix = Matrix()
    matrix.postScale(scale, scale)
    matrix.postTranslate(
        (newWidth - scaledWidth) / 2f,
        (newHeight - scaledHeight) / 2f
    )

    val outputBitmap = Bitmap.createBitmap(newWidth, newHeight, bitmap.config)
    outputBitmap.eraseColor(Color.WHITE)
    
    Canvas(outputBitmap).drawBitmap(
        bitmap,
        matrix,
        null
    )

    return outputBitmap
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接