Je cherche une solution au problème suivant: comment modifier la taille d'une variable Bitmap
en une taille fixe (par exemple, 512x128). Le rapport hauteur/largeur du contenu bitmap doit être préservé.
Je pense que ça devrait être quelque chose comme ça:
créer un bitmap vide de 512x128
redimensionne le bitmap d'origine pour l'adapter aux 512x128 pixels tout en conservant le rapport hauteur/largeur
copier la mise à l'échelle dans le bitmap vide (centré)
Quel est le moyen le plus simple d'y parvenir?
La raison de tout cela est que la GridView
perturbe la mise en page lorsque le format de l'image diffère de celui de l'autre. Voici une capture d'écran (toutes les images sauf la dernière ont un rapport d'aspect de 4: 1):
Essayez ceci, calculez le rapport puis redimensionnez.
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;
}
La réponse de Coen Damen ne respecte pas toujours la hauteur maximale et la largeur maximale. Voici une réponse qui:
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;
}
}
Je suis tombé sur le même problème à plusieurs reprises dans mes projets et à chaque fois, faute de temps (et de paresse), je me contenterais d'une solution moins qu'optimale. Mais récemment, j'ai trouvé un peu de temps pour lutter contre ce problème particulier. Voici ma solution et j'espère que cela aidera quelqu'un en bout de ligne ...
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;
}
et assurez-vous que les variables dstWidth
et dstHeight
sont obtenues à partir de src.getWidth()*scale
et src.getHeight()*scale
, où scale
est une valeur que vous devez déterminer pour vous assurer que l'image bitmap redimensionnée convient à 512x128.
Je pense que la réponse de @ Coen n’est pas la bonne solution pour cette question. J'avais aussi besoin d'une méthode comme celle-ci mais je voulais une image carrée.
Voici ma solution pour l'image carrée;
public static Bitmap resizeBitmapImageForFitSquare(Bitmap image, int maxResolution) {
if (maxResolution <= 0)
return image;
int width = image.getWidth();
int height = image.getHeight();
float ratio = (width >= height) ? (float)maxResolution/width :(float)maxResolution/height;
int finalWidth = (int) ((float)width * ratio);
int finalHeight = (int) ((float)height * ratio);
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
if (image.getWidth() == image.getHeight())
return image;
else {
//fit height and width
int left = 0;
int top = 0;
if(image.getWidth() != maxResolution)
left = (maxResolution - image.getWidth()) / 2;
if(image.getHeight() != maxResolution)
top = (maxResolution - image.getHeight()) / 2;
Bitmap bitmap = Bitmap.createBitmap(maxResolution, maxResolution, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(image, left, top, null);
canvas.save();
canvas.restore();
return bitmap;
}
}