31 votes

Redimensionnement proportionnel de l'image

J'ai un petit problème pour mettre à l'échelle mes images à une taille prédéfinie. Je me demandais - puisque c'est purement mathématique - s'il existait une sorte d'algorithme logique commun qui fonctionne dans tous les langages (PHP, ActionScript, Javascript, etc.) pour mettre les images à l'échelle de manière proportionnelle.

C'est ce que j'utilise en ce moment :

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);
}

Mais ça ne fonctionne pas correctement. Les images sont mises à l'échelle proportionnellement, bien sûr, mais la taille n'est pas fixée à 300 (ni en largeur ni en hauteur). C'est assez logique, mais je me demandais s'il existait un moyen simple et infaillible de mettre les images à l'échelle de manière proportionnelle.

64voto

Dark Shikari Points 6178
ratio = MIN( maxWidth / width, maxHeight/ height );
width = ratio * width;
height = ratio * height;

Assurez-vous que toutes les divisions sont à virgule flottante.

4voto

Josh Millard Points 939

C'est Dark Shikari qui l'a. Votre solution telle qu'énoncée dans la question échoue parce que vous n'êtes pas premièrement établir quel est le rapport entre la taille du dimenson et la taille maximale, et puis en réduisant les deux dimensions par ce rapport supérieur.

L'utilisation par votre solution actuelle d'une analyse sérielle et conditionnelle d'une violation dimensionnelle potentielle puis de l'autre ne fonctionnera pas.

Notez également que si vous voulez haut de gamme images, ta solution actuelle ne marchera pas, et celle de Dark Shikari marchera encore.

2voto

Alex Weinstein Points 5839

Je vous recommande de ne pas écrire ce code vous-même ; il y a des myriades de détails au niveau du pixel qui prennent un temps fou pour être corrects. Utilisez ImageMagick, c'est la meilleure bibliothèque graphique qui existe.

2voto

Arvin Points 1392

Voici comment je procède :

+ (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;
}

0voto

Bogdan Ciocoiu Points 64

Voici une fonction que j'ai développée pour mon site et que vous pourriez utiliser. Elle est basée sur votre réponse ci-dessus.

Il fait d'autres choses que le traitement de l'image - veuillez supprimer tout ce qui est inutile .

<?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);
}

?>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X