android - pixeles - Cambiar el tamaño de un mapa de bits a un valor fijo, pero sin cambiar la relación de aspecto
convertir video a 16:9 online (4)
y asegúrese de que tanto dstWidth
como dstHeight
se obtienen de las src.getWidth()*scale
y src.getHeight()*scale
, donde scale
es un valor que debe determinar para asegurarse de que el mapa de bits escalado se ajuste a 512x128.
Estoy buscando una solución para el siguiente problema: cómo cambiar el tamaño de un Bitmap
de Bitmap
a un tamaño fijo (por ejemplo, 512x128). La relación de aspecto del contenido del mapa de bits debe conservarse.
Creo que debería ser algo como esto:
crea un mapa de bits vacío de 512x128
escala el mapa de bits original hacia abajo para adaptarse a los 512x128 píxeles manteniendo la relación de aspecto
copia la escala en el mapa de bits vacío (centrado)
¿Cuál es la forma más simple de lograr esto?
La razón de todo esto es que GridView
altera el diseño cuando la relación de aspecto de una imagen difiere de la otra. Aquí hay una captura de pantalla (todas las imágenes, excepto la última, tienen una relación de aspecto de 4: 1):
He tropezado con el mismo problema varias veces en mis proyectos y cada vez debido a la falta de tiempo (y la pereza) estaría satisfecho con una solución menos que óptima. Pero recientemente encontré algo de tiempo para resolver este problema en particular. Aquí está mi solución y espero que ayude a alguien en el futuro ...
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;
}
La respuesta de Coen Damen no siempre respeta la altura máxima y el ancho máximo. Aquí hay una respuesta que hace:
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;
}
}
Pruebe esto, calcule la proporción y luego cambie la escala.
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;
}