1

アップロード時にユーザーがアップロードした画像を縮小しようとしています。
これは問題ありませんが、サイズを具体的に説明したいと思います。

あらゆる形状の画像(あらゆる幅/高さの正方形または長方形)を取り、それを縮小するアルゴリズムの作成に苦労していることについて、いくつかのアドバイスを探しています。

この画像は、ターゲットボックスサイズに縮小する必要があります(これは変更されますが、変数に格納されます)。
したがって、アスペクト比を維持しながら、幅と高さの両方がターゲットの幅と高さよりも大きくなるように画像を縮小する必要があります。 。ただし、ただ..
ターゲットサイズは画像のトリミングに使用されるため、エッジなどの周りに空白はありません。

さまざまな寸法の画像に基づいて正しいサイズ変更を作成する背後にあるアルゴリズムだけを探しています-トリミングを処理でき、ほとんどの場合はサイズ変更もできますが、いくつか失敗するため、連絡を取ります。

私は実際にはPHPコードをもっと疑似的に求めているわけではありません。どちらも明らかに問題ありません。

親切に感謝します。

現在のコード..しかし、私は非常に多くの反復を経験しましたが、これはもうまったく機能しない可能性があります..:P

$image = $image_orig->clone();
$wRatio = $imageprops['width'] / $dimensions[0];   // imageprops = original image dimens.
$hRatio = $imageprops['height'] / $dimensions[1];  // $dimensions[0] = new width
$maxRatio = max($wRatio,$hRatio);                  // $dimensions[1] = new height

var_dump('thumb');

$ratio = ($imageprops['width'] - $dimensions[0]) > ($imageprops['height'] - $dimensions[1]);
$shape = ($imageprops['width'] > $imageprops['height']);
$error = ($imageprops['width'] / $imageprops['height']);

if( $error < 0.95 || $error > 1.05 ) { // its NOT a square
    if($shape){  // longer width
        $scale = $imageprops['height'] / $dimensions[0];
        var_dump('1');

        $height = $imageprops['height'] / $scale;
        $image->scaleImage(0, $height);
    } else {
        $scale = $imageprops['width'] / $dimensions[1];
        var_dump('2');

        $width = $imageprops['width'] / $scale;
        $image->scaleImage($width, 0);


    }
} elseif($ratio) { // is square
    $scale = $imageprops['height'] / $dimensions[1];
    $newWidth = $imageprops['width'] / $scale;
    $extra = 0;

    $height = $dimensions[1]+$extra;
    $image->scaleImage(0, $height);
} else {
    $scale = $imageprops['width'] / $dimensions[0];
    $newHeight = $imageprops['height'] / $scale;
    $extra = 0;

    $width = $dimensions[0]+$extra;
    $image->scaleImage($width, 0);

}


$image_size = $image->getImageGeometry();

$image->cropImage($dimensions[0], $dimensions[1],($image_size['width']-$dimensions[0])/2,($image_size['height']-$dimensions[1])/2);
4

2 に答える 2

10

注意:私は、元の投稿者が彼の質問を編集して、元の質問が尋ねていると私が信じていたものを変更した点を明確にするものを含める前に、この回答を書きました。


したがって、達成しようとしていることを解決するために投げかけることができるいくつかの概念とアイデアがあります。(Gravity Cropping、Content Aware Cropping、Content Aware Rescalingなど)

元の画像のサイズは常に小さくしているため、基本的には画像の一部を「切り取る」ことを目的としています。このように非常に:

ここに画像の説明を入力してください

ただし、問題は、画像の無関係なセグメントでトリミングされないように、画像の最適な領域を選択することを頻繁に確認したいということです。これはコンテンツ対応の画像トリミングと呼ばれ、「コンテンツ対応の画像トリミング」を使用して検索するだけで、豊富な情報を見つけることができます。

とにかく、先に進むと、正確なユースケースによっては、実際には画像から何も切り取られたくないことに気付くかもしれません。代わりに、画像を「液体スケールしてトリミング」して、「コンテンツ」を実行する必要があります。サイズ変更を意識する」。コンテンツ対応のサイズ変更との違いは、サイズ変更は画像のすべてのアスペクト比を無視し、代わりに画像のサイズを流動的に変更するために隣接するエッジと色を確認することです。

ですから、幸いなことに、Imagickそれは非常に独自の[liquidRescaleImage][3]機能を備えています。

あなたはそれを次のように使うことができます

$im->liquidRescaleImage(480, 260, 3, 18);

Liquid Rescaleを使用すると、非常にうまく再スケールアウトできます。以下の例は完璧ではありませんが、アスペクト比を調整するだけでなく、liquidRescaleが画像の構成を変更することを実際に確認できるように、意図的に完璧ではない例を作成しました。

オリジナル

オリジナル

コンテンツアウェアリキッドリスケール(450x350)

再スケール

ただし、画像を拡大縮小してアスペクト比を維持したい場合は、Flickrなどのサイトで、画像を最も長くして値と等しくするサイトを実行することをお勧めします。(たとえば、Flickrには6つほどの異なる寸法サイズがあります)

写真のサイズをウェブに適したサイズに変更します。各画像には、75x75および150x150の正方形のサムネイルと、100、240、320、500、640、800 *、1024、1600、および2048 *ピクセルのバージョン(最長の辺の長さ)があります。 、および元のファイル。

Flickrのサイズ変更ポリシーを複製する基本クラス...

<?php    
class Scale {        
    public function getImageScale($x, $y, $longestLength, $allowDistort = false) {
        //Set the default NEW values to be the old, in case it doesn't even need scaling
        list($nx, $ny) = array($x, $y);            
            if ($x > $y) {                   
                if ($longestLength > $x && !$allowDistort) {
                    return array($x, $y);
                }
                $r = $x / $longestLength;
                return array($longestLength, $y / $r);
            } else {
                if ($longestLength > $x && !$allowDistort) {
                    return array($x, $y);
                }
                $r = $y / $longestLength;
                return array($x / $r, $longestLength);
            }
        return array($nx, $ny);
    }       
}

そして、次のように画像の寸法を渡す場合:

$originalImageX = 480;
$originalImageY = 260;    
$scale = new Scale();
var_dump($scale->getImageScale($originalImageX,$originalImageY,120 ) );    

/* Outputs
   array(2) {
  [0]=>
  int(120)
  [1]=>
  int(65)
} */

また、GitにはこのContent Aware Croppingクラスがあります。これは、以前に基本クラス/構造を自分のプロジェクトで使用するように調整したので、うまく機能することがわかっています。このクラスのライセンスについてはよくわかりませんが、明らかにそれを見て、以前と同じように自分に合ったものを切り取ることができます。

https://gist.github.com/2468935#file_content_aware_image.php

(そしてPS。次回は質問のすべての情報をまっすぐに提供してください...)

于 2012-11-20T17:23:19.037 に答える
2

私の個人的なスクリプトライブラリxDから、これが必要な場合はDunno:必要な$ maxW $ maxHを指定するだけで、サムネイルにも同じことができ、それに比例して画像が縮小されます。

スクリプトには、ほぼ同じ2つの部分があります。1つはサムネイル用で、もう1つは実際の画像用です。

list($w, $h) = getimagesize($file);
$maxW = 1024;
$maxH = 786;
$thumbMaxW = 138;
$thumbMaxH = 92;

$newW = $w;
$newH = $h;

if($w > $thumbMaxW OR $h > $thumbMaxH){
    if($w>=$h){
        $thumbW = $thumbMaxW;
        $thumbRatio = $w/$thumbMaxW;
        $thumbH = (int)($h/$thumbRatio);
    } else {
        $thumbH = $thumbMaxH;
        $thumbRatio = $h/$thumbMaxH;
        $thumbW = (int)($w/$thumbRatio);
    }
} else {
    $thumbW = $w;
    $thumbH = $h;
}
--------------------------------------------

if($w > $maxW OR $h > $maxH){
    if($w >= $h){
        $newW = $maxW;
        $reduction = $w/$newW;
        $newH = (int)   ($h/$reduction);
    }

    if($h > $w){
        $newH = $maxH;
        $reduction = $h/$newH;
        $newW = (int)($w/$reduction);
    }
} else {
    $newW = $w;
    $newH = $h;
}
于 2012-11-20T16:57:02.020 に答える