2009-06-13 11 views
2

Je travaille sur permettre aux utilisateurs de télécharger des photos de profil pour mon site. L'exemple classique de ce que je suis en train d'éviter est plentyoffish.com chaque image des utilisateurs est biaisé et semble très laid:Comment puis-je recadrer/mettre à l'échelle les images utilisateur afin de pouvoir afficher des vignettes de taille fixe sans les incliner et les étirer?

alt text

Alors, comment puis-je progmatically culture/créer des versions de taille standard d'une image sans biaisé démontré ci-dessus?

+1

Quelle langue/plate-forme utilisez-vous? –

+1

Remplacez les images par celles de chickipedia. Ils ont tous l'air magnifique. –

Répondre

5

Eh bien, vous devez avoir une hauteur et une largeur maximum, supposons que la taille de l'image dont vous disposez est carrée, disons 100x100.

Lorsqu'un utilisateur télécharge une image en obtient les dimensions, alors déterminez laquelle est la plus grande, la hauteur ou la largeur.

Ensuite, prenez la plus grande mesure et obtenez le rapport de cette mesure à la mesure de votre cible, puis utilisez ce rapport pour mettre à l'échelle à la fois la hauteur et la largeur. Donc, si l'utilisateur télécharge une image de 500 hauteur et 450 largeur, comme la hauteur est la plus grande, vous divisez 100 par 500, la taille de votre vignette. Cela nous donne .2 comme le ratio. ce qui signifie que la largeur deviendra 90, donc vous rétrécirez à 100x90, et aucune distorsion ne se produirait.

1

Voici du code (C#) que j'ai utilisé pour faire un redimensionnement, similaire à la méthode suggérée par blowdart. Il suffit de remplacer les « 300 » s avec la taille maximale d'un côté dans votre cas:

private Bitmap ScaleImage(Image oldImage) 
    { 
     double resizeFactor = 1; 

     if (oldImage.Width > 300 || oldImage.Height > 300) 
     { 
      double widthFactor = Convert.ToDouble(oldImage.Width)/300; 
      double heightFactor = Convert.ToDouble(oldImage.Height)/300; 
      resizeFactor = Math.Max(widthFactor, heightFactor); 

     } 
     int width = Convert.ToInt32(oldImage.Width/resizeFactor); 
     int height = Convert.ToInt32(oldImage.Height/resizeFactor); 
     Bitmap newImage = new Bitmap(width, height); 
     Graphics g = Graphics.FromImage(newImage); 
     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     g.DrawImage(oldImage, 0, 0, newImage.Width, newImage.Height); 
     return newImage; 
    } 
0

OU: Si vous dimensions fixes encore comme, vous suivez les instructions de blowdart mais calculer le plus grand rapport à la place: 100px/450px = 0,22 ..

  • largeur: 100px
  • hauteur: 111.11..px -> culture du sol ((111,11 à 100)/2) sur le dessus et vers le bas 100px.

EDIT: Ou laisser l'utilisateur choisir la façon de recadrer la plus grande dimension.

0

Utilisez ImageMagick. Sur l'utilisation de la ligne de commande:

convert -thumbnail geometry 
0

J'ai fait cette fonction pour PHP il y a un moment qui fonctionne très bien pour cela et d'autres scénarios:

<?php 

function Image($source, $crop = null, $resize = null) 
{ 
    $source = ImageCreateFromString(file_get_contents($source)); 

    if (is_resource($source) === true) 
    { 
     $width = imagesx($source); 
     $height = imagesy($source); 

     if (isset($crop) === true) 
     { 
      $crop = array_filter(explode('/', $crop), 'is_numeric'); 

      if (count($crop) == 2) 
      { 
       if (($width/$height) > ($crop[0]/$crop[1])) 
       { 
        $width = $height * ($crop[0]/$crop[1]); 
        $crop = array((imagesx($source) - $width)/2, 0); 
       } 

       else if (($width/$height) < ($crop[0]/$crop[1])) 
       { 
        $height = $width/($crop[0]/$crop[1]); 
        $crop = array(0, (imagesy($source) - $height)/2); 
       } 
      } 

      else 
      { 
       $crop = array(0, 0); 
      } 
     } 

     else 
     { 
      $crop = array(0, 0); 
     } 

     if (isset($resize) === true) 
     { 
      $resize = array_filter(explode('*', $resize), 'is_numeric'); 

      if (count($resize) >= 1) 
      { 
       if (empty($resize[0]) === true) 
       { 
        $resize[0] = round($resize[1] * $width/$height); 
       } 

       else if (empty($resize[1]) === true) 
       { 
        $resize[1] = round($resize[0] * $height/$width); 
       } 
      } 

      else 
      { 
       $resize = array($width, $height); 
      } 
     } 

     else 
     { 
      $resize = array($width, $height); 
     } 

     $result = ImageCreateTrueColor($resize[0], $resize[1]); 

     if (is_resource($result) === true) 
     { 
      ImageCopyResampled($result, $source, 0, 0, $crop[0], $crop[1], $resize[0], $resize[1], $width, $height); 
      ImageDestroy($source); 

      header('Content-Type: image/jpeg'); 

      ImageJPEG($result, null, 90); 
      ImageDestroy($result); 
     } 
    } 

    return false; 
} 

Image('/path/to/your/image.jpg', '1/1', '100*'); 
Image('/path/to/your/image.jpg', '1/1', '100*100'); 
Image('/path/to/your/image.jpg', '1/1', '100*500'); 

?> 
0

Voici une commande bash j'ai jeté ensemble pour y parvenir en utilisant L'outil de conversion d'ImageMagick. Pour un ensemble d'images assis dans le répertoire parent, un certain portrait, un certain paysage, pour créer des images dans le répertoire courant mis à l'échelle de 600x400, le recadrage des images portrait du centre et de mise à l'échelle simplement les images du paysage:

for f in ../*jpg; do 
    echo $f; 
    size=`identify $f|cut -d' ' -f 3`; 
    w=`echo $size|cut -dx -f 1`; 
    h=`echo $size|cut -dx -f 2`; 
    if [ $w -gt $h ]; then 
     convert $f -thumbnail 600x400 `basename $f`; 
    else 
     convert $f -scale 600x -crop 600x400+0+`echo "((600*($h/$w))/2)" | bc | sed 's/\..*//'` `basename $f`; 
    fi; 
done;