15

エンドユーザーがデザイナーで画像のサイズと位置を設定できるアプリケーションがあります。仕様では、画像を含むコントロールに「引き伸ばす」必要があるため、エンドユーザーはぎこちなく引き伸ばされた画像になってしまう可能性があります。

ユーザーの画像サイズ設定を支援するために、ユーザーが画像のアスペクト比を簡単に修正して、画像が引き伸ばされて見えないようにするスマートリサイザー機能を実装することを考えています。

これを解決する簡単な方法は、実際には2つのオプションを提供することです。1)幅からのスケール2)高さからのスケール。ユーザーが方法を選択し、アルゴリズムが元のアスペクト比を使用して画像のサイズを調整します。例:画像はデザイナーに200x200として表示されますが、元の画像は1024x768ピクセルです。ユーザーが「幅からスマートサイズ」を選択すると、元のアスペクト比が約1.333であるため、新しいサイズは約200x150になります。

それは問題ありませんが、再計算の基になる次元を尋ねることで、アルゴリズムをよりスマートにし、ユーザーを煩わせないようにするにはどうすればよいでしょうか。

4

10 に答える 10

33

私があなたの仕様を正しく解釈しているのであれば、エンドユーザーが最初にレイアウトした結果よりも大きくない結果が必要です。2つの次元の一方を縮小し、もう一方を同じままにします。つまり、新しいサイズは、元のアスペクト比を維持するために、一方の方向でデザイナースペースを埋め、もう一方の方向でサイズを短くする必要があります。

original_ratio = original_width / original_height
designer_ratio = designer_width / designer_height
if original_ratio > designer_ratio
    designer_height = designer_width / original_ratio
else
    designer_width = designer_height * original_ratio

多くの場合、整数座標で作業しますが、上記の比率を生成するための除算は浮動小数点である必要があります。これは、より整数に対応するように数式を再配置したものです。整数に最大幅*高さを処理できる範囲があることを確認してください。

if original_width * designer_height > designer_width * original_height
    designer_height = (designer_width * original_height) / original_width
else
    designer_width = (designer_height * original_width) / original_height
于 2010-06-09T19:01:20.337 に答える
13
于 2012-09-11T01:49:28.297 に答える
3

私もこれを知りたかったのですが、私が見たのは、幅または高さのスケーリングの無限の例だけでしたが、他のものをあふれさせる可能性がありました。

  • ループを必要とせずに幅と高さのサイズを変更します
  • 画像の元の寸法を超えない

private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
  double srcWidth = img.Source.Width;
  double srcHeight = img.Source.Height;

  double resizeWidth = srcWidth;
  double resizeHeight = srcHeight;

  double aspect = resizeWidth / resizeHeight;

  if (resizeWidth > maxWidth)
  {
    resizeWidth = maxWidth;
    resizeHeight = resizeWidth / aspect;
  }
  if (resizeHeight > maxHeight)
  {
    aspect = resizeWidth / resizeHeight;
    resizeHeight = maxHeight;
    resizeWidth = resizeHeight * aspect;
  }

  img.Width = resizeWidth;
  img.Height = resizeHeight;
}
于 2011-04-13T19:55:41.343 に答える
2

上記の提案を採用し、最大の高さ/幅の範囲内でスケールアップ/スケールダウンしました。ここにそのためのPythonコードがあり、制限内にとどまりながら物事を回転させるためのサポートも追加されています。

def _resize(image、dimensions、rotate = None):"""画像のサイズを指定したサイズにできるだけ近づけます。画像はdjangoimage-model-fieldです。

    Will both scale up and down the image to meet this while keeping the proportions
    in width and height

"""

if image and os.path.isfile(image.path):

    im = pil.open(image.path)
    logging.debug('resizing image from %s x %s --> %s x %s ' % (im.size[0], im.size[1], dimensions[0], dimensions[1]))

    if rotate:
        logging.debug('first rotating image %s' % rotate)
        im = im.rotate(90)

    srcWidth = Decimal(im.size[0])
    srcHeight = Decimal(im.size[1])

    resizeWidth = srcWidth
    resizeHeight = srcHeight

    aspect = resizeWidth / resizeHeight # Decimal

    logging.debug('resize aspect is %s' % aspect)

    if resizeWidth > dimensions[0] or resizeHeight > dimensions[1]:
        # if width or height is bigger we need to shrink things
        if resizeWidth > dimensions[0]:
            resizeWidth = Decimal(dimensions[0])
            resizeHeight = resizeWidth / aspect

        if resizeHeight > dimensions[1] :
            aspect = resizeWidth / resizeHeight
            resizeHeight = Decimal(dimensions[1])
            resizeWidth = resizeHeight * aspect

    else:
        # if both width and height are smaller we need to increase size
        if resizeWidth < dimensions[0]:
            resizeWidth = Decimal(dimensions[0])
            resizeHeight = resizeWidth / aspect

        if resizeHeight > dimensions[1] :
            aspect = resizeWidth / resizeHeight
            resizeHeight = Decimal(dimensions[1])
            resizeWidth = resizeHeight * aspect

    im = im.resize((resizeWidth, resizeHeight), pil.ANTIALIAS)

    logging.debug('resized image to %s %s' % im.size)
    im.save(image.path)

else:
    # no action, due to no image or no image in path
    pass

return image
于 2013-02-16T11:33:33.820 に答える
2

両方のバリエーション(「幅によるスケール」と「高さによるスケール」)の新しい寸法を計算してから、ディスプレイに収まるものを使用します。

または、「バウンディングボックス」のアスペクト比を計算して、元の画像のアスペクト比と比較することもできます。どちらのアスペクト比が大きいかに応じて、高さまたは幅をスケーリングする必要があります。

サイズ変更プロセスを制限して、すべての場合に「幅によるスケーリング」が行われるようにすることもできます。次に、画像のサイズを変更するには、ユーザーは常に画像の幅を変更する必要があります。高さは常に自動的に調整されます。

于 2010-06-09T18:40:10.890 に答える
1

ウィンドウ内の(元の)拡大縮小された画像、つまりデザイナーの領域を可能な限り表示したいので、元の画像の幅または高さのいずれか大きい方を取り、それを200に拡大縮小します。 。擬似コード(幅、高さは元の寸法です):

if (width > height) {
    scaledWidth = 200;
    scaledHeight = (height * 200) / width;
} else {
    scaledHeight = 200;
    scaledWidth = (width * 200) / height;
}
于 2010-06-09T18:47:26.917 に答える
1

これが私の解決策です、

a=アスペクトsw=元の画像の幅sh=元の画像の高さdw=要求された最大幅dh=要求された最大の高さ

swとshには、最終的にサイズ変更された値が含まれます

コードはPHPです:

$a = $sw / $sh;

if($a > 1){
    //  wider image
    if($sw != $dw){
        $rt = $dw / $sw;
        $sw = $sw * $rt;
        $sh = $sh * $rt;
    }

    if($sh > $dh){
        $rt = $dh / $sh;
        $sw = $sw * $rt;
        $sh = $sh * $rt;
    }
}else{
    //  taller image
    if($sh != $dh){
        $rt = $dh / $sh;
        $sh = $sh * $rt;
        $sw = $sw * $rt;
    }

    if($sw > $dw){
        $rt = $dw / $sw;
        $sh = $sh * $rt;
        $sw = $sw * $rt;
    }
}
于 2013-03-18T14:51:02.953 に答える
1

https://stackoverflow.com/a/5654847/1055015に基づいてjavascriptでサイズを縮小および拡大する私のソリューション

var scale =  function (srcWidth, srcHeight, maxWidth, maxHeight) {

      let resizeWidth  = srcWidth;
      let resizeHeight = srcHeight;

      let aspect = resizeWidth / resizeHeight;
      let scaleX = maxWidth / srcWidth;
      let scaleY = maxHeight / srcHeight;
      let scale  = Math.min(scaleX, scaleY);

      resizeWidth *= scale;
      resizeHeight *= scale;

      if (resizeWidth > maxWidth) {
        resizeWidth  = maxWidth;
        resizeHeight = resizeWidth / aspect;
      }

      if (resizeHeight > maxHeight) {
        aspect       = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth  = resizeHeight * aspect;
      }

      return {
        width : resizeWidth,
        height: resizeHeight,
      };
    }
于 2017-05-15T11:29:25.503 に答える
0

両方の次元に必要なスケールを計算してから、2つのうち小さい方を選択する必要があります。

于 2010-06-09T19:02:06.203 に答える
0

この方法を使用して、画像のサイズをFHDの方法に変更しました

if ( width >= height) {
  var original_ratio = width / height
  new_width = 1080 * original_ratio
  console.log("new new_width = " + Math.round(new_width) );
  console.log("new new_height = 1080");
} else {
  var original_ratio =  height / width
  new_height = 1080 * original_ratio
  console.log("new new_height = " + Math.round(new_height) );
  console.log("new new_width = 1080");
}

1080を新しいサイズに変更できます。

少なくとも誰かに役立つことを願っています。

于 2017-01-22T11:56:23.627 に答える