ユーザーが自分のサイトのプロフィール写真をアップロードできるように取り組んでいます。私が回避しようとしているものの典型的な例は、各ユーザーの画像が歪んでいて非常に醜いように見えるppleoffish.comです。
では、上記のようにゆがめずに標準サイズの画像をプログラム的にトリミング/作成するにはどうすればよいでしょうか?
ユーザーが自分のサイトのプロフィール写真をアップロードできるように取り組んでいます。私が回避しようとしているものの典型的な例は、各ユーザーの画像が歪んでいて非常に醜いように見えるppleoffish.comです。
では、上記のようにゆがめずに標準サイズの画像をプログラム的にトリミング/作成するにはどうすればよいでしょうか?
そうですね、最大の高さと幅が必要です。利用可能な画像サイズが正方形、たとえば 100x100 であると仮定しましょう。
ユーザーが画像をアップロードすると、そのサイズが取得され、高さと幅のどちらが大きいかがわかります。
次に、最大の測定値を取得し、その測定値と目標測定値の比率を取得し、その比率を使用して高さと幅の両方をスケーリングします。
したがって、ユーザーが高さ 500、幅 450 の画像をアップロードした場合、高さが最大になるため、サムネイル サイズは 100 を 500 で割ります。これにより、比率として .2 が得られます。つまり、幅が 90 になるので、100x90 に縮小しても歪みは発生しません。
これは、blowdart によって提案された方法と同様に、サイズ変更を行うために使用したコード (C#) です。「300」を、ケースの片側の最大サイズに置き換えるだけです。
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;
}
または: それでも固定サイズが必要な場合は、blowdart の指示に従いますが、代わりに最大の比率を計算します: 100px / 450px = .22..
EDIT : または、ユーザーが最大の寸法を切り取る方法を選択できるようにします。
これは、ImageMagick の変換ツールを使用してこれを達成するためにまとめた bash コマンドです。親ディレクトリにある一連の画像、いくつかの縦向き、いくつかの横向きの場合、現在のディレクトリに 600x400 にスケーリングされた画像を作成し、中央から縦向きの画像をトリミングし、横向きの画像を単純にスケーリングします。
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;
私はこの関数を PHP 用に少し前に作成しました。これは、このシナリオやその他のシナリオでうまく機能します。
<?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');
?>
ImageMagickを使用します。コマンドラインで次を使用します。
convert -thumbnail geometry