調べてみましたが、わかりませんでした。
たとえば、画像に241x76
は合計が18,316 pixels (241 * 76)
。サイズ変更のルールは、ピクセル数が通過できないこと10,000
です。10,000
次に、アスペクト比を維持し、ピクセル未満の新しいサイズを取得するにはどうすればよいですか?
調べてみましたが、わかりませんでした。
たとえば、画像に241x76
は合計が18,316 pixels (241 * 76)
。サイズ変更のルールは、ピクセル数が通過できないこと10,000
です。10,000
次に、アスペクト比を維持し、ピクセル未満の新しいサイズを取得するにはどうすればよいですか?
擬似コード:
pixels = width * height
if (pixels > 10000) then
ratio = width / height
scale = sqrt(pixels / 10000)
height2 = floor(height / scale)
width2 = floor(ratio * height / scale)
ASSERT width2 * height2 <= 10000
end if
実装に関係するすべての計算にはratio
、浮動小数点演算を使用することを忘れないでください。scale
Python
import math
def capDimensions(width, height, maxPixels=10000):
pixels = width * height
if (pixels <= maxPixels):
return (width, height)
ratio = float(width) / height
scale = math.sqrt(float(pixels) / maxPixels)
height2 = int(float(height) / scale)
width2 = int(ratio * height / scale)
return (width2, height2)
Image
オブジェクトを取得して返すC#の代替関数:
using System.Drawing.Drawing2D;
public Image resizeMaxPixels(int maxPixelCount, Image originalImg)
{
Double pixelCount = originalImg.Width * originalImg.Height;
if (pixelCount < maxPixelCount) //no downsize needed
{
return originalImg;
}
else
{
//EDIT: not actually needed - scaleRatio takes care of this
//Double aspectRatio = originalImg.Width / originalImg.Height;
//scale varies as the square root of the ratio (width x height):
Double scaleRatio = Math.Sqrt(maxPixelCount / pixelCount);
Int32 newWidth = (Int32)(originalImg.Width * scaleRatio);
Int32 newHeight = (Int32)(originalImg.Height * scaleRatio);
Bitmap newImg = new Bitmap(newWidth, newHeight);
//this keeps the quality as good as possible when resizing
using (Graphics gr = Graphics.FromImage(newImg))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(originalImg, new Rectangle(0, 0, newWidth, newHeight));
}
return newImg;
}
}
品質を損なうことなく画像のサイズを変更するための答えからのグラフィックコードを使用
編集:アスペクト比の計算は、実際にはここでは関係ありません。これは、幅と高さを合計ピクセル比の(平方根)で既にスケーリングしているためです。これを使用して(またはその逆newWidth
)に基づいて計算することもできますが、これは必須ではありません。newHeight
Deestanのコードは正方形の画像に対して機能しますが、アスペクト比が1と異なる状況では、平方根は機能しません。アスペクト比を2で割った値にスケールを合わせる必要があります。
観察(Python):
def capDimensions(width, height, maxPixels):
pixels = width * height
if (pixels <= maxPixels):
return (width, height)
ratio = float(width) / height
scale = (float(pixels) / maxPixels)**(width/(height*2))
height2 = round(float(height) / scale)
width2 = round(ratio * height2)
return (width2, height2)
結果を比較してみましょう。
初期サイズ:450x600 初期ピクセル:270000
119850ピクセルにできるだけ近づけるようにサイズを変更しようとしています。
Deestanのアルゴリズムを使用:capDimensions:300x400サイズ変更されたピクセル:67500
変更されたアルゴリズム:capDimensionsを使用します。332x442のサイズ変更されたピクセル:82668
これは、楽しみのために、自分で数学の問題を解こうとしているときに、今日の午後に思いついたものです。私のコードは正常に機能しているようです。いくつかの異なる形状とサイズの画像でテストしました。浮動小数点変数を使用してください。そうしないと、計算が失敗します。
orig_width=1920
orig_height=1080
orig_pixels=(orig_width * orig_height)
max_pixels=180000
if (orig_pixels <= max_pixels) {
# use original image
}
else {
# scale image down
ratio=sqrt(orig_pixels / max_pixels)
new_width=floor(orig_width / ratio)
new_height=floor(orig_height / ratio)
}
1920x1080 (1.77778 ratio) becomes 565x318 (1.77673 ratio, 179,670 pixels)
1000x1000 (1.00000 ratio) becomes 424x424 (1.00000 ratio, 179,776 pixels)
200x1200 (0.16667 ratio) becomes 173x1039 (0.16651 ratio, 179,747 pixels)
width2 = int(ratio * height / scale)
だろう
width2 = int(ratio * height2)
これにより、アスペクト比がより適切に維持される可能性があるためです(height2が切り捨てられているため)。
'sc'のような別の変数を導入せずに、
new_height = floor(sqrt(m / r))と 書くことができます。
と
new_width = floor(sqrt(m * r))
m = max_pixels(ここでは:10.000)、r = ratio = w / h(ここでは:241/76 = 3.171)
両方の結果は互いに独立しています!
各new_valueから、(指定:new_height)new_width = floor(new_height * r) (指定:new_width)new_height = floor(new_width / r) を使用して他のディメンションを計算できます。
値をクリッピングするため(床関数)、次元の両方のペアは、それらの比率が元の比率にどれだけ近いかが異なる場合があります。あなたはより良いペアを選ぶでしょう。