31

画像を適切に事前定義されたサイズにスケーリングするのに少し問題があります。私は疑問に思っていました-それは純粋に数学であるため、画像を比例してスケーリングするためにすべての言語(PHP、ActionScript、Javascriptなど)で機能するある種の一般的な論理アルゴリズムがあるかどうか。

私は現時点でこれを使用しています:

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

しかし、それは正しく動作しません。確かに、画像は比例して拡大縮小されますが、サイズは 300 に設定されていません (幅または高さのいずれか)。それは理にかなっていますが、画像を比例してスケーリングするための簡単で簡単な方法があるかどうか疑問に思っていました.

4

6 に答える 6

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

すべての除算が浮動小数点であることを確認してください。

于 2008-09-22T15:24:33.407 に答える
4

闇のシカリにはあります。質問に記載されているソリューションは失敗します。これは、最初にどのディメンションのサイズと最大サイズの比率が大きいかを確認してから、両方のディメンションをその比率で縮小していないためです。

現在のソリューションで使用されている、1 つの潜在的な寸法違反の連続的な条件付き分析は機能しません。

また、画像をアップスケールしたい場合、現在のソリューションはうまくいきませんが、ダーク シカリはうまくいくことにも注意してください。

于 2008-09-22T17:01:14.657 に答える
2

これが私がそれを行う方法です:

+ (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;
}
于 2012-02-29T19:44:52.197 に答える
2

このコードを自分で書かないことをお勧めします。無数のピクセルレベルの詳細があり、正しく理解するにはかなりの時間がかかります。ImageMagick を使用してください。最高のグラフィックス ライブラリです。

于 2008-09-22T15:23:57.260 に答える
0

この関数を比例的にスケーリングするように作成しました。指定された幅、高さ、およびオプションで必要な最大幅/高さを使用します(指定された幅と高さに依存します)

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

利用方法:

            $getScale = scaleProportional(600,200,500);
            $targ_w = $getScale['width']; //returns 500
            $targ_h = $getScale['height']; //returns 16,6666667
于 2012-01-22T12:26:31.777 に答える
0

これは、私が自分のサイト用に開発した関数です。使用することをお勧めします。上記の回答に基づいています。

画像処理だけでなく、他のことも行います。不要なものはすべて削除してください

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

?>
于 2011-10-12T20:39:22.727 に答える