php - saber - Cálculo de la relación de tamaño de imagen para cambiar el tamaño
como saber el tamaño de una imagen jpg (12)
Tengo un ancho y altura fijos definidos para cambiar el tamaño de una imagen. Sin embargo, tengo un problema con esto, porque la imagen puede tener cualquier tipo de relación de tamaño (puede ser vertical o horizontal ). En este caso, el ancho y la altura fijos causan un problema. Quiero calcular el ancho y la altura de una manera más inteligente.
Por ejemplo, digamos que he definido ancho 1024px y alto 768px . Y quiero cambiar el tamaño de una imagen que es vertical (altura 1100px y ancho 200px) . Por lo tanto, en mi caso cambiará el tamaño a tamaño fijo (1024x768) , por lo que el ancho aumentará de 100px a 768px , y será muy feo. Del mismo modo, si la imagen tiene una altura inferior a 768px , aumentará la altura por la fuerza a 768px .
Por lo tanto, me gustaría calcular el nuevo tamaño de imagen en función de la relación de tamaño de imagen original. Digamos si la imagen de ejemplo anterior debe cambiar de tamaño a la altura máxima de 768px , pero ¿qué pasa con el ancho? ya es menor que mi "ancho máximo", que es 200px , ¿debería el ancho permanecer sin cambios? o debería reducirse aún más?
Del mismo modo, si la imagen tiene una altura de 200 px y un ancho de 1100 px . Entonces, el ancho debería reducirse a 1024px , pero ¿qué pasa con la altura?
El tercer problema es que, supongamos que tanto la altura como el ancho son más que la altura máxima y el ancho máximo, digamos ancho: 1100px y altura: 4000px . Ahora, dado que el ancho y la altura son mayores que el ancho máximo y la altura máxima, pero la imagen es vertical, la hará horizontal. Entonces, ¿cómo puedo verificar si en este caso si debo cambiar el tamaño de la imagen de acuerdo con la altura máxima o de acuerdo con el ancho máximo?
apreciaría cualquier ayuda con esto.
Aquí está el código de mi bolsa personal de código de cambio de tamaño de la imagen. Primero, la información que necesita:
list($originalWidth, $originalHeight) = getimagesize($imageFile);
$ratio = $originalWidth / $originalHeight;
Luego, este algoritmo ajusta la imagen al tamaño objetivo de la mejor manera posible, manteniendo la relación de aspecto original, sin estirar la imagen más grande que el original:
$targetWidth = $targetHeight = min($size, max($originalWidth, $originalHeight));
if ($ratio < 1) {
$targetWidth = $targetHeight * $ratio;
} else {
$targetHeight = $targetWidth / $ratio;
}
$srcWidth = $originalWidth;
$srcHeight = $originalHeight;
$srcX = $srcY = 0;
Esto recorta la imagen para completar el tamaño objetivo por completo, sin estirarlo:
$targetWidth = $targetHeight = min($originalWidth, $originalHeight, $size);
if ($ratio < 1) {
$srcX = 0;
$srcY = ($originalHeight / 2) - ($originalWidth / 2);
$srcWidth = $srcHeight = $originalWidth;
} else {
$srcY = 0;
$srcX = ($originalWidth / 2) - ($originalHeight / 2);
$srcWidth = $srcHeight = $originalHeight;
}
Y esto hace el cambio de tamaño real:
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
imagecopyresampled($targetImage, $originalImage, 0, 0, $srcX, $srcY, $targetWidth, $targetHeight, $srcWidth, $srcHeight);
En este caso, el $size
es solo un número para ancho y alto (tamaño de objetivo cuadrado). Estoy seguro de que puedes modificarlo para usar objetivos no cuadrados. También debería darle una inspiración sobre qué otros algoritmos de cambio de tamaño puede usar.
Compruebe el código php a continuación:
$new_width = 1024;
$new_height = 768;
$this_image = "images/my_image";
list($width, $height, $type, $attr) = getimagesize("$this_image");
if ($width > $height) {
$image_height = floor(($height/$width)*$new_width);
$image_width = $new_width;
} else {
$image_width = floor(($width/$height)*$new_height);
$image_height = $new_height;
}
echo "<img src=''$this_image'' height=''$image_height'' width=''$image_width''>";
Deberías redimensionarlo dependiendo de qué propiedad esté más lejos del valor máximo. Luego, calcule la razón.
if(($w - $w_max) > ($h - $h_max)) {
$w_new = $w_max;
$h_new = (int) ($h * ($w_max / $w));
}
else {
$h_new = $h_max;
$w_new = (int) ($w * ($h_max / $h));
}
Este ejemplo reducirá el tamaño de una imagen para que se ajuste a una relación de aspecto perfecta de píxeles definidos (16: 9) creando una imagen no mayor que un límite especificado (1200 x 675).
Establezca su relación de imagen y cualquier límite superior:
const RATIO_W = 16;
const RATIO_H = 9;
const RATIO_MULIPLIER_UPPER_LIMIT = 75;
Calcule el nuevo ancho y alto de la imagen
list($imageWidth, $imageHeight) = getimagesize($path_to_image);
if( ($imageWidth / $imageHeight) === (self::RATIO_W / self::RATIO_H) ){
return;
// Find closest ratio multiple to image size
if($imageWidth > $imageHeight){
// landscape
$ratioMultiple = round($imageHeight / self::RATIO_H, 0, PHP_ROUND_HALF_DOWN);
}else{
// portrait
$ratioMultiple = round($imageWidth / self::RATIO_W, 0, PHP_ROUND_HALF_DOWN);
}
$newWidth = $ratioMultiple * self::RATIO_W;
$newHeight = $ratioMultiple * self::RATIO_H;
if($newWidth > self::RATIO_W * self::RATIO_MULIPLIER_UPPER_LIMIT|| $newHeight > self::RATIO_H * self::RATIO_MULIPLIER_UPPER_LIMIT){
// File is larger than upper limit
$ratioMultiple = self::RATIO_MULIPLIER_UPPER_LIMIT;
}
$this->tweakMultiplier($ratioMultiple, $imageWidth, $imageHeight);
$newWidth = $ratioMultiple * self::RATIO_W;
$newHeight = $ratioMultiple * self::RATIO_H;
Cambiar el tamaño de la imagen
$originalImage = imagecreatefromjpeg( $tempImagePath );
$newImage = imagecreatetruecolor($newWidth, $newHeight);
imagefilledrectangle($newImage, 0, 0, $newWidth, $newHeight, imagecolorallocate($newImage, 255, 255, 255));
imagecopyresampled($newImage, $originalImage, 0, 0, 0, 0, $newWidth, $newHeight, $imageWidth, $imageHeight);
imagejpeg($newImage, $tempImagePath, 100);
Pasa por factores hasta que ambas dimensiones sean menores que el tamaño de la imagen original
protected function tweakMultiplier( &$ratioMultiple, $fitInsideWidth, $fitInsideHeight ){
$newWidth = $ratioMultiple * self::RATIO_W;
$newHeight = $ratioMultiple * self::RATIO_H;
if($newWidth > $fitInsideWidth || $newHeight > $fitInsideHeight){
echo " Tweak ";
$ratioMultiple--;
$this->tweakMultiplier($ratioMultiple, $fitInsideWidth, $fitInsideHeight);
}else{
return;
}
}
Llegué a esta pregunta y no encontré una respuesta adecuada, así que me puse en mi lugar para responder la pregunta.
Empecé con una lógica básica, y después de consultar a un amigo mío que es un poco mejor en matemáticas, esto es lo que se nos ocurrió.
function calculate_dimensions($width,$height,$max){
if($width != $height){
if($width > $height){
$t_height = $max;
$t_width = min(($width * $t_height)/$height);
}
if($height > $width){
$t_width = $max;
$t_height = min(($t_width * $height)/$width)
}
}else{
if($width > $max){
$t_width = $t_height = $max;
}
}
$res = [''height''=>$t_height,''width''=>$t_width]
return $res;
}
Este fragmento de código es reutilizable, así que olvídate. simplemente páselo por la dimensión máxima más pequeña permitida, y calculará la dimensión del lado más grande, por lo que obtendrá una dimensión correctamente escalada, en la que podrá centrar el recorte, lo que dará como resultado una imagen cuadrada de imagen correctamente contraída y recortada. esto es útil para cosas como fotos de perfil y miniaturas.
crédito a mi amigo, Justin Gillett por su brillante sugerencia de multiplicación cruzada.
Lo que desea es mantener la relación de aspecto de su imagen original. Esta es la relación entre el ancho y la altura de la imagen. Entonces calcula el factor por el cual tiene que cambiar el tamaño de la imagen en la dirección vertical y horizontal y luego mantener la mayor de las dos. En pseudocódigo:
target_height = 768
target_width = 1024
# v_fact and h_fact are the factor by which the original vertical / horizontal
# image sizes should be multiplied to get the image to your target size.
v_fact = target_height / im_height
h_fact = target_width / im_width
# you want to resize the image by the same factor in both vertical
# and horizontal direction, so you need to pick the correct factor from
# v_fact / h_fact so that the largest (relative to target) of the new height/width
# equals the target height/width and the smallest is lower than the target.
# this is the lowest of the two factors
im_fact = min(v_fact, h_fact)
new_height = im_height * im_fact
new_width = im_width * im_fact
image.resize(new_width, new_height)
Lo que necesita es ''mantener'' la relación ancho / alto. Originalmente tienes una imagen de tamaño (wxh) 500x1000
, esta relación ancho / alto es 0.5
. Suponiendo que está cambiando de 1000
a 768
de altura, el ancho de su resultado sería 0.5 * 768 = 384
.
Otro ejemplo, 1800 x 1200
y su nueva altura es 200
, entonces su nuevo ancho es 300
porque 300/200
es 1.5
y 1800/1200
también es 1.5
.
Buena suerte.
Qué tal esto:
double ratio = imageWidth/imageHeight;
int newHeight = Math.min(displayHeight, displayWidth / ratio);
int newWidth = Math.min(displayWidth, displayHeight * ratio);
Si se da o no la altura máxima o el ancho, usando la lógica @ (jilles de wit)
consideraciones: ¡estas ya deberían estar definidas!
$mh = given height limit; //optional
$mw = given width limit; //optional
$height = $nh =[your original height];
$width = $nw =[your original width];
El código
if($mh || $mw){
if(is_numeric($mh)){$h_fact = $mh / $nh;}
if(is_numeric($mw)){$v_fact = $mw / $nw;}
if(is_numeric($v_fact) && is_numeric($h_fact) ){$im_fact = min($v_fact, $h_fact);}else{$im_fact=is_numeric($v_fact)?$v_fact:$h_fact;}
$nw = $nw * $im_fact;
$nh = $nh * $im_fact;
}
remuestreo
$dst_img = imagecreatetruecolor($nw,$nh);
imagecopyresampled ($dst_img, $image, 0, 0, 0, 0, $nw, $nh, $width , $height);
esto está funcionando.
function calculateDimensions($width,$height,$maxwidth,$maxheight)
{
if($width != $height)
{
if($width > $height)
{
$t_width = $maxwidth;
$t_height = (($t_width * $height)/$width);
//fix height
if($t_height > $maxheight)
{
$t_height = $maxheight;
$t_width = (($width * $t_height)/$height);
}
}
else
{
$t_height = $maxheight;
$t_width = (($width * $t_height)/$height);
//fix width
if($t_width > $maxwidth)
{
$t_width = $maxwidth;
$t_height = (($t_width * $height)/$width);
}
}
}
else
$t_width = $t_height = min($maxheight,$maxwidth);
return array(''height''=>(int)$t_height,''width''=>(int)$t_width);
}
$ratio = $originalWidth / $originalHeight
si quieres cambiar la altura:
$targetWidth = $targetHeight * $ratio
si quieres cambiar el ancho:
$targetHeight = $targetWidth / $ratio
class Image_Aspect_Ratio_Resize {
var $image_to_resize;
var $new_width;
var $new_height;
var $ratio;
var $new_image_name;
var $save_folder;
function resize() {
if (!file_exists($this->image_to_resize)) {
exit("File " . $this->image_to_resize . " does not exist.");
}
$info = GetImageSize($this->image_to_resize);
if (empty($info)) {
exit("The file " . $this->image_to_resize . " doesn''t seem to be an image.");
}
$width = $info[0];
$height = $info[1];
$mime = $info[''mime''];
/* Keep Aspect Ratio? */
if ($this->ratio) {
$thumb = ($this->new_width < $width && $this->new_height < $height) ? true : false; // Thumbnail
$bigger_image = ($this->new_width > $width || $this->new_height > $height) ? true : false; // Bigger Image
if ($thumb) {
if ($this->new_width >= $this->new_height) {
$x = ($width / $this->new_width);
$this->new_height = ($height / $x);
} else if ($this->new_height >= $this->new_width) {
$x = ($height / $this->new_height);
$this->new_width = ($width / $x);
}
} else if ($bigger_image) {
if ($this->new_width >= $width) {
$x = ($this->new_width / $width);
$this->new_height = ($height * $x);
} else if ($this->new_height >= $height) {
$x = ($this->new_height / $height);
$this->new_width = ($width * $x);
}
}
}
$type = substr(strrchr($mime, ''/''), 1);
switch ($type) {
case ''jpeg'':
$image_create_func = ''ImageCreateFromJPEG'';
$image_save_func = ''ImageJPEG'';
$new_image_ext = ''jpg'';
break;
case ''png'':
$image_create_func = ''ImageCreateFromPNG'';
$image_save_func = ''ImagePNG'';
$new_image_ext = ''png'';
break;
case ''bmp'':
$image_create_func = ''ImageCreateFromBMP'';
$image_save_func = ''ImageBMP'';
$new_image_ext = ''bmp'';
break;
case ''gif'':
$image_create_func = ''ImageCreateFromGIF'';
$image_save_func = ''ImageGIF'';
$new_image_ext = ''gif'';
break;
case ''vnd.wap.wbmp'':
$image_create_func = ''ImageCreateFromWBMP'';
$image_save_func = ''ImageWBMP'';
$new_image_ext = ''bmp'';
break;
case ''xbm'':
$image_create_func = ''ImageCreateFromXBM'';
$image_save_func = ''ImageXBM'';
$new_image_ext = ''xbm'';
break;
default:
$image_create_func = ''ImageCreateFromJPEG'';
$image_save_func = ''ImageJPEG'';
$new_image_ext = ''jpg'';
}
// New Image
$image_c = ImageCreateTrueColor($this->new_width, $this->new_height);
$new_image = $image_create_func($this->image_to_resize);
ImageCopyResampled($image_c, $new_image, 0, 0, 0, 0, $this->new_width, $this->new_height, $width, $height);
if ($this->save_folder) {
if ($this->new_image_name) {
$new_name = $this->new_image_name . ''.'' . $new_image_ext;
} else {
$new_name = $this->new_thumb_name(basename($this->image_to_resize)) . ''_resized.'' . $new_image_ext;
}
$save_path = $this->save_folder . $new_name;
} else {
/* Show the image without saving it to a folder */
header("Content-Type: " . $mime);
$image_save_func($image_c);
$save_path = '''';
}
$process = $image_save_func($image_c, $save_path);
return array(''result'' => $process, ''new_file_path'' => $save_path);
}}
/* Llamada de función */
$resize_image = new Image_Aspect_Ratio_Resize;
$new_width = (int) $_POST[''new_width''];
$new_height = (int) $_POST[''new_height''];
$resize_image->new_width = $new_width;
$resize_image->new_height = $new_height;
$resize_image->image_to_resize = $image; // Full Path to the file
$resize_image->ratio = true; // Keep aspect ratio
// Name of the new image (optional) - If it''s not set a new will be added automatically
$resize_image->new_image_name = ''water_lilies_thumbnail'';
/* Path where the new image should be saved. If it''s not set the script will output the image without saving it */
$resize_image->save_folder = ''thumbs/'';
$process = $resize_image->resize(); // Output image