8

画像のサイズを固定サイズに変更する必要があります。ただし、幅と高さの間の要素を維持する必要があります。

画像のサイズを から に変更したいと238 (w) X 182 (h)します210 / 150

私が今していることは次のとおりです。

Original width / target width = 1.333333
Original Height / target Height = 1.213333

今、私は最小の要因を取ります。

以来、私は常に正しい幅を持っています238 / 1.333333 = 210。しかし、高さはまだ160です。

160写真を台無しにせずに高さを下げるにはどうすればよいですか?

トリミングする必要がありますか?もしそうなら、どのように?

4

11 に答える 11

26

この解決策は基本的に Can Berk Güder のものと同じですが、しばらく書いてコメントした後、投稿したいと思いました。

この関数は、指定したサイズとまったく同じ大きさのサムネイルを作成します。サムネイルのサイズに合わせて画像のサイズが変更されます。両方向に正確に収まらない場合は、サムネイルの中央に配置されます。広範なコメントが進行状況を説明しています。

function thumbnail_box($img, $box_w, $box_h) {
    //create the image, of the required size
    $new = imagecreatetruecolor($box_w, $box_h);
    if($new === false) {
        //creation failed -- probably not enough memory
        return null;
    }


    //Fill the image with a light grey 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($new, 200, 200, 205);
    imagefill($new, 0, 0, $fill);

    //compute resize ratio
    $hratio = $box_h / imagesy($img);
    $wratio = $box_w / imagesx($img);
    $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($img) * $ratio);
    $sx = floor(imagesx($img) * $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(($box_h - $sy) / 2);
    $m_x = floor(($box_w - $sx) / 2);

    //Copy the image data, and resample
    //
    //If you want a fast and ugly thumbnail,
    //replace imagecopyresampled with imagecopyresized
    if(!imagecopyresampled($new, $img,
        $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($img), imagesy($img)) //src w, h (the full size of the original)
    ) {
        //copy failed
        imagedestroy($new);
        return null;
    }
    //copy successful
    return $new;
}

使用例:

$i = imagecreatefromjpeg("img.jpg");
$thumb = thumbnail_box($i, 210, 150);
imagedestroy($i);

if(is_null($thumb)) {
    /* image creation or copying failed */
    header('HTTP/1.1 500 Internal Server Error');
    exit();
}
header('Content-Type: image/jpeg');
imagejpeg($thumb);
于 2009-04-14T12:21:19.037 に答える
11

これは画像をトリミングしませんが、必要に応じて新しい画像の周囲にスペースを残します。これは、サムネイルを作成するときに(トリミングするよりも)優れたアプローチだと思います。

$w = 210;
$h = 150;

$orig_w = imagesx($original);
$orig_h = imagesy($original);

$w_ratio = $orig_w / $w;
$h_ratio = $orig_h / $h;

$ratio = $w_ratio > $h_ratio ? $w_ratio : $h_ratio;

$dst_w = $orig_w / $ratio;
$dst_h = $orig_h / $ratio;
$dst_x = ($w - $dst_w) / 2;
$dst_y = ($h - $dst_h) / 2;

$thumbnail = imagecreatetruecolor($w, $h);

imagecopyresampled($thumbnail, $original, $dst_x, $dst_y,
                   0, 0, $dst_w, $dst_h, $orig_w, $orig_h);
于 2009-04-14T11:35:01.800 に答える
2

Imagickはありますか?もしそうなら、あなたはそれで画像をロードして、次のようなことをすることができますthumbnailimage()

そこで、パラメータ(高さまたは幅)のいずれかをスキップでき、正しくサイズ変更されます。

于 2009-04-14T11:22:54.293 に答える
2

たぶんPHPThumbを見てください(GDとImageMagickで動作します)

于 2009-04-14T11:27:38.493 に答える
2

大きな画像から高品質で高速なサムネイルを生成するためのヒント: (php.net サイトから)

サムネイルの生成を2段階で行う場合:

  1. 高速サイズ変更を使用して、元の画像から最終的なサイズの 2 倍の中間画像へ
  2. 高品質のリサンプルを使用した中間イメージから最終的なサムネイルまで

その後、これははるかに高速になります。ステップ 1 のサイズ変更は、そのサイズに対して比較的低品質ですが、ステップ 2 の品質がまともなほど十分な追加の解像度があり、中間画像は高品質のリサンプル (2:1 のサイズ変更でうまく機能します) に十分なほど小さいです。非常に速く進みます。

于 2009-04-14T14:20:54.227 に答える
1

画像が制限内に収まるようにサイズを変更してから、空白の部分を埋めたいと思います。したがって、上記の例では、高さがOKになるようにサイズを変更してから、左右に背景色を塗りつぶします(両端に7ピクセルあると思います)。

于 2009-04-14T11:36:35.260 に答える
1

PHPソースのWebページ内からの画像のサイズ変更は問題になる可能性があります。より大きな画像(ディスク上で2 + MBに近づく)は非常に大きくなる可能性があるため、処理に32MBを超えるメモリが必要になります。

そのため、最大128MBのメモリを使用できるCLIベースのスクリプトから実行するか、必要なだけ使用する標準のコマンドラインから実行する傾向があります。

# where to put the original file/image. It gets resized back 
# it was originally found (current directory)
SAFE=/home/website/PHOTOS/originals
# no more than 640x640 when finished, and always proportional
MAXSIZE=640
# the larger image is in /home/website/PHOTOS/, moved to .../originals
# and the resized image back to the parent dir.
cd $SAFE/.. && mv "$1" "$SAFE/$1" && \
   convert "$SAFE/$1" -resize $MAXSIZE\x$MAXSIZE\> "$1"

「変換」は、ImageMagickコマンドラインツールの一部です。

于 2009-04-14T11:38:03.243 に答える
1

少し混乱があると思います.元の比率を維持してサイズを変更するだけの場合、正しい操作は次のとおりです。

$ratio = $originalWidth / $originalHeight;
if(//you start from the width, and want to find the height){
 $newWidth = $x;
 $newHeight = $x / $ratio;
}else if(//you start from the height, and want to find the width){
 $newHeight = $x;
 $newWidth = $x * $ratio;
}

それ以外の場合、プレフィックス付きの newWidth と newHeight を変更できず、サムの比率が元の比率と異なる場合、唯一の方法はトリミングするか、サムに境界線を追加することです。

あなたが切り口を取りたい場合は、この機能が役立ちます(私は何年も前に5分で書いたので、改善が必要かもしれません..たとえば、jpgでのみ機能します;):

    function thumb_cut($nomeimage, $source_path, $destination_path, $new_width, $new_height){
      list($width, $height, $type, $attr) = getimagesize($source_path.$nomeimage);
      if($type == 2){
        if($width > $new_width){
          $new_width = $width;
          $new_height = $height;
        }
        $compression = 100;
        $destimg = imagecreatetruecolor($new_width,$new_height) or die("Problems creating the image");
        $srcimg = ImageCreateFromJPEG($source_path.$nomeimage) or die("problem opening the image");
        $w = ImageSX($srcimg);
        $h = ImageSY($srcimg);
        $ro = $new_width/$new_height;
        $ri = $w/$h;
        if($ro<$ri){
          $par = "h";
        }else{
          $par = "w";
        }
        if($par == "h"){
          $ih = $h;
          $conv = $new_width/$new_height;
          $iw = $conv*$ih;
          $cw = ($w/2)-($iw/2);
          $ch = ($h/2)-($ih/2);
        }else if($par == "w"){
          $iw = $w;
          $conv = $new_height/$new_width;
          $ih = $conv*$iw;
          $cw = ($w/2)-($iw/2);
          $ch = ($h/2)-($ih/2);
        }
        ImageCopyResampled($destimg,$srcimg,0,0,$cw,$ch,$new_width,$new_height,$iw,$ih) or die("problems with resize");
        ImageJPEG($destimg,$destination_path.$nomeimage,$compression) or die("problems with storing new image");
      }
    }
于 2009-04-14T12:17:55.910 に答える
1

are these thumbnails? if they are, cropping is not a huge problem. we do it all the time. i don't even shy away from cropping arbitrary ratios into crippled quadratic thumbnails, completely messing up the image (yes, i'm that hardcore), if it just looks good. this is a designers answer to a technical question, but still. don't fear the crop!

于 2009-04-14T11:56:31.110 に答える
1

テクニックは次のとおりです。

  1. 一方の寸法が一致し、他方の寸法が目的の寸法を超えるように画像のサイズを変更します
  2. リサイズした画像の中心から希望のサイズの画像を取り出します。

最後に、サイズ変更の計算方法に戸惑う場合は、ソース イメージと宛先イメージの比率が同じ場合、次の関係が成り立つことを思い出してください。

SourceWidth / SourceHeight = DestinationWidth / DestinationHeight

3 つのパラメータを知っていれば、4 番目のパラメータを簡単に計算できます。

これについての記事を書きました:
ASP/PHP を使用して画像に合わせてトリミングする

于 2009-04-18T04:18:35.323 に答える
0

目標サイズに到達するには、上下から5ピクセルをトリミングする必要がありますが、これにより画像が台無しになる可能性があります。

実際には、ターゲットの幅または高さを設定してから、他の寸法を同じ比率で調整する必要があります。

于 2009-04-14T11:30:56.350 に答える