我正在为以下问题寻求解决方案:如何将Bitmap
的大小更改为固定大小(例如512x128)。位图内容的高宽比必须保留。将位图调整为固定值,但不改变宽高比
我想应该是这样的:
创建一个空的512x128位图
规模原始位下降到与保持宽高比
配合512x128像素将缩放复制到空位图(居中)
实现此目的的最简单方法是什么?
所有这一切的原因是,GridView
当图像的宽高比不同时,会使布局紊乱。下面是一个屏幕截图(除了最后一个的所有图像为4的纵横比:1):
我正在为以下问题寻求解决方案:如何将Bitmap
的大小更改为固定大小(例如512x128)。位图内容的高宽比必须保留。将位图调整为固定值,但不改变宽高比
我想应该是这样的:
创建一个空的512x128位图
规模原始位下降到与保持宽高比
配合512x128像素将缩放复制到空位图(居中)
实现此目的的最简单方法是什么?
所有这一切的原因是,GridView
当图像的宽高比不同时,会使布局紊乱。下面是一个屏幕截图(除了最后一个的所有图像为4的纵横比:1):
试试这个,计算比率,然后重新调整。
private Bitmap scaleBitmap(Bitmap bm) {
int width = bm.getWidth();
int height = bm.getHeight();
Log.v("Pictures", "Width and height are " + width + "--" + height);
if (width > height) {
// landscape
float ratio = (float) width/maxWidth;
width = maxWidth;
height = (int)(height/ratio);
} else if (height > width) {
// portrait
float ratio = (float) height/maxHeight;
height = maxHeight;
width = (int)(width/ratio);
} else {
// square
height = maxHeight;
width = maxWidth;
}
Log.v("Pictures", "after scaling Width and height are " + width + "--" + height);
bm = Bitmap.createScaledBitmap(bm, width, height, true);
return bm;
}
并确保两者dstWidth
和dstHeight
从src.getWidth()*scale
和src.getHeight()*scale
获得,其中scale
是您需要确定的值,以确保缩放的位图适合512x128内部。
'createScaledBitmap'不能解决我的问题。这就是我已经使用的。在这个例子中,最后一幅图像已经被缩放了。 – 2013-02-27 23:32:26
如果你已经有一个按比例缩小的位图(宽度小于512或者在你的例子中高度小于128),只需在GridView项目的ImageView中将这些属性设置为android:layout_width =“512dp”和android:layout_height =“128dp “和android:scaleType =”center“或android:scaleType =”centerInside“ – 2013-02-28 00:38:29
根据我的解释,示例中的最后一幅图像已经缩小了,所以它已经是最大值了。 128px高。尽管如此,图像视图显示它比其他图像更大。另外我不想用512x128dp网格的图像视图。 – 2013-02-28 23:14:39
我在我的项目中偶然发现过相同的问题,每次都因缺乏时间(和懒惰)而感到满意,我不满足于最佳解决方案。但最近我发现了一些时间来打击这个特殊问题。这里是我的解决方案,我希望它可以帮助别人了线......
Bitmap scaleDownLargeImageWithAspectRatio(Bitmap image)
{
int imaheVerticalAspectRatio,imageHorizontalAspectRatio;
float bestFitScalingFactor=0;
float percesionValue=(float) 0.2;
//getAspect Ratio of Image
int imageHeight=(int) (Math.ceil((double) image.getHeight()/100)*100);
int imageWidth=(int) (Math.ceil((double) image.getWidth()/100)*100);
int GCD=BigInteger.valueOf(imageHeight).gcd(BigInteger.valueOf(imageWidth)).intValue();
imaheVerticalAspectRatio=imageHeight/GCD;
imageHorizontalAspectRatio=imageWidth/GCD;
Log.i("scaleDownLargeImageWIthAspectRatio","Image Dimensions(W:H): "+imageWidth+":"+imageHeight);
Log.i("scaleDownLargeImageWIthAspectRatio","Image AspectRatio(W:H): "+imageHorizontalAspectRatio+":"+imaheVerticalAspectRatio);
//getContainer Dimensions
int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
int displayHeight = getWindowManager().getDefaultDisplay().getHeight();
//I wanted to show the image to fit the entire device, as a best case. So my ccontainer dimensions were displayWidth & displayHeight. For your case, you will need to fetch container dimensions at run time or you can pass static values to these two parameters
int leftMargin = 0;
int rightMargin = 0;
int topMargin = 0;
int bottomMargin = 0;
int containerWidth = displayWidth - (leftMargin + rightMargin);
int containerHeight = displayHeight - (topMargin + bottomMargin);
Log.i("scaleDownLargeImageWIthAspectRatio","Container dimensions(W:H): "+containerWidth+":"+containerHeight);
//iterate to get bestFitScaleFactor per constraints
while((imageHorizontalAspectRatio*bestFitScalingFactor <= containerWidth) &&
(imaheVerticalAspectRatio*bestFitScalingFactor<= containerHeight))
{
bestFitScalingFactor+=percesionValue;
}
//return bestFit bitmap
int bestFitHeight=(int) (imaheVerticalAspectRatio*bestFitScalingFactor);
int bestFitWidth=(int) (imageHorizontalAspectRatio*bestFitScalingFactor);
Log.i("scaleDownLargeImageWIthAspectRatio","bestFitScalingFactor: "+bestFitScalingFactor);
Log.i("scaleDownLargeImageWIthAspectRatio","bestFitOutPutDimesions(W:H): "+bestFitWidth+":"+bestFitHeight);
image=Bitmap.createScaledBitmap(image, bestFitWidth,bestFitHeight, true);
//Position the bitmap centre of the container
int leftPadding=(containerWidth-image.getWidth())/2;
int topPadding=(containerHeight-image.getHeight())/2;
Bitmap backDrop=Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.RGB_565);
Canvas can = new Canvas(backDrop);
can.drawBitmap(image, leftPadding, topPadding, null);
return backDrop;
}
Coen Damen的回答并不总是尊重最大高度和最大宽度。 这里的答案是:
private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
if (maxHeight > 0 && maxWidth > 0) {
int width = image.getWidth();
int height = image.getHeight();
float ratioBitmap = (float) width/(float) height;
float ratioMax = (float) maxWidth/(float) maxHeight;
int finalWidth = maxWidth;
int finalHeight = maxHeight;
if (ratioMax > 1) {
finalWidth = (int) ((float)maxHeight * ratioBitmap);
} else {
finalHeight = (int) ((float)maxWidth/ratioBitmap);
}
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
return image;
} else {
return image;
}
}
窃取我的答案很好。当然maxWidth和maxHeight是类变量而不是方法参数。 – 2017-01-11 09:36:22
加一个简单的解决方案。但我会改变诠释比率浮动/双倍比率,因为int/int可能会产生例外,当它尝试除以0. – 2014-08-05 15:00:48
真棒简单的解决方案!但是使用浮点数来代替整数是必须的。否则结果在大多数情况下可能是错误的(例如,当它应该是1.4时比率变为1)。 – xip 2014-11-10 20:42:51
@Hikaru你是对的,想要做到这一点,但从来没有去过。感谢您的编辑和提醒 - ) – 2014-11-11 08:21:17