2008-09-22 32 views
31

Estoy teniendo un pequeño problema para escalar mis imágenes a un tamaño predefinido. Me estaba preguntando, ya que es puramente matemática, si hay algún tipo de algoritmo lógico común que funciona en todos los idiomas (PHP, ActionScript, Javascript, etc.) para escalar las imágenes proporcionalmente.Tamaño de imagen proporcional

estoy usando esto en el momento:

var maxHeight = 300; 
var maxWidth = 300; 

var ratio:Number = height/width; 

if (height > maxHeight) { 
    height = maxHeight; 
    width = Math.round(height/ratio); 
} 

else if(width > maxWidth) { 
    width = maxWidth; 
    height = Math.round(width * ratio); 
} 

Pero no funciona correctamente. Las imágenes se escalan proporcionalmente, por supuesto, pero el tamaño no se establece en 300 (ya sea en ancho o en altura). Tiene algún sentido, pero me preguntaba si existe una forma fácil de escalar imágenes proporcionalmente.

Respuesta

64
ratio = MIN(maxWidth/width, maxHeight/ height); 
width = ratio * width; 
height = ratio * height; 

Asegúrate de que todas las divisiones sean de coma flotante.

2

Recomendaría no escribir este código usted mismo; hay miríadas de detalles a nivel de píxel que tardan un tiempo serio en hacerlo bien. Use ImageMagick, es la mejor biblioteca de gráficos que existe.

4

Dark Shikari lo tiene. Su solución como se indica en la pregunta falla porque no está primero estableciendo cuál es la relación tamaño a tamaño máximo de dimenson es mayor y luego reduciendo ambas dimensiones en esa proporción mayor.

El uso de su solución actual de un análisis condicional y en serie de una posible violación dimensional y luego la otra no funcionará.

Tenga en cuenta también que si desea imágenes de lujo, su solución actual no volará, y Dark Shikari lo hará de nuevo.

0

Aquí hay una función que he desarrollado para mi sitio, es posible que desee utilizar. Está basado en tu respuesta anterior.

Hace otras cosas, no solo el procesamiento de imagen - por favor eliminar todo lo que es innecesario.

<?php 

$thumb_width = 500; 
$thumb_height = 500; 

if ($handle = opendir('to-do')) { 
    echo "Directory handle: $handle<br />"; 
    echo "Files:<br /><br />"; 

    /* This is the correct way to loop over the directory. */ 
    while (false !== ($file = readdir($handle))) { 

     if (($file != ".") && ($file != "..")){ 
      echo "$file"; 

      $original_path = "to-do/" . $file; 

      $source_image = ImageCreateFromJPEG($original_path); 
      $thumb_width = $thumb_width; 
      $thumb_height = $thumb_height; 

      // Create the image, of the required size 
      $thumbnail = imagecreatetruecolor($thumb_width, $thumb_height); 
      if($thumbnail === false) { 
       //creation failed -- probably not enough memory 
       return null; 
      } 

      // Fill the image with a white color (this will be visible in the padding around the image, 
      // if the aspect ratios of the image and the thumbnail do not match) 
      // Replace this with any color you want, or comment it out for black. 
      // I used grey for testing =) 
      $fill = imagecolorallocate($thumbnail, 255, 255, 255); 
      imagefill($thumbnail, 0, 0, $fill); 

      // Compute resize ratio 
      $hratio = $thumb_height/imagesy($source_image); 
      $wratio = $thumb_width/imagesx($source_image); 
      $ratio = min($hratio, $wratio); 

      // If the source is smaller than the thumbnail size, 
      // Don't resize -- add a margin instead 
      // (that is, dont magnify images) 
      if ($ratio > 1.0) 
       $ratio = 1.0; 

      // Compute sizes 
      $sy = floor(imagesy($source_image) * $ratio); 
      $sx = floor(imagesx($source_image) * $ratio); 

      // Compute margins 
      // Using these margins centers the image in the thumbnail. 
      // If you always want the image to the top left, set both of these to 0 
      $m_y = floor(($thumb_height - $sy)/2); 
      $m_x = floor(($thumb_width - $sx)/2); 

      // Copy the image data, and resample 
      // If you want a fast and ugly thumbnail, replace imagecopyresampled with imagecopyresized 
      if (!imagecopyresampled($thumbnail, $source_image, 
       $m_x, $m_y, //dest x, y (margins) 
       0, 0, //src x, y (0,0 means top left) 
       $sx, $sy,//dest w, h (resample to this size (computed above) 
       imagesx($source_image), imagesy($source_image)) //src w, h (the full size of the original) 
      ) { 
       //copy failed 
       imagedestroy($thumbnail); 
       return null; 
      } 

      /* Set the new file name */ 
      $thumbnail_file_name = $file; 

      /* Apply changes on the original image and write the result on the disk */ 
      ImageJPEG($thumbnail, $complete_path . "done/" . $thumbnail_file_name); 
      unset($source_image); 
      unset($thumbnail); 
      unset($original_path); 
      unset($targeted_image_size); 

      echo " done<br />"; 

     } 

    } 

    closedir($handle); 
} 

?> 
+0

Así que recuerde que debe limpiarse, hay muchas secciones extraíbles. –

0

bien Hice esta función a escala proporcional, que utiliza una anchura dada, la altura, y opcionalmente el max anchura/altura u quiere (depende de la anchura dada y altura)

function scaleProportional($img_w,$img_h,$max=50) 
    { 
     $w = 0; 
     $h = 0; 

     $img_w > $img_h ? $w = $img_w/$img_h : $w = 1; 
     $img_h > $img_w ? $h = $img_h/$img_w : $h = 1; 

     $ws = $w > $h ? $ws = ($w/$w) * $max : $ws = (1/$h) * $max; 
     $hs = $h > $w ? $hs = ($h/$h) * $max : $hs = (1/$w) * $max; 

     return array(
      'width'=>$ws, 
      'height'=>$hs 
     ); 
    } 

uso :

  $getScale = scaleProportional(600,200,500); 
      $targ_w = $getScale['width']; //returns 500 
      $targ_h = $getScale['height']; //returns 16,6666667 
1

Aquí es cómo lo hago:

+ (NSSize) scaleHeight:(NSSize)origSize 
      newHeight:(CGFloat)height { 

    NSSize newSize = NSZeroSize; 
    if (origSize.height == 0) return newSize; 

    newSize.height = height; 
    CGFloat factor = (height/origSize.height); 
    newSize.width = (origSize.width * factor); 

    return newSize; 
} 

+ (NSSize) scaleWidth:(NSSize)origSize 
      newWidth:(CGFloat)width { 

    NSSize newSize = NSZeroSize; 
    if (origSize.width == 0) return newSize; 

    newSize.width = width; 
    CGFloat factor = (width/origSize.width); 
    newSize.height = (origSize.height * factor); 

    return newSize; 
} 
Cuestiones relacionadas