HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0125
Marksmanアスペクト比を維持しつつ指定した大きさ以下に画像を縮小する6解決


Marksman

リンク

2020/1/25(Sat) 17:37:00|NO.89336

表題の通りです

画像を表示させるエリアが一定サイズで指定されているとして(ViewX, ViewY)
そのエリアより大きなサイズ(PicX, PicY)の画像ファイルを読み込み表示させようとした場合
その画像の縦横比を維持しつつエリアギリギリいっぱいの大きさへ縮小したいと考えています。
(C#のPictureboxにあるコンテナ内に収めるAutosizeプロパティのようなイメージ)

ただ単に画像を縮小、または比率維持で縮小ならわかったのですが(PicX,Y * 倍数)
数値の上限(ViewX, ViewYというエリア)が決まるとわからなくなってしまいました。

以上よろしくお願いいたします。



この記事に返信する


よっぴー

リンク

2020/1/25(Sat) 17:56:40|NO.89337

こういうやつですか


dim picwidth dim picheight dim originalwidth dim originalheight dim stretchwidth dim stretchheight dialog"",16,"" if stat==0 :end picfile=refstr picwidth=512 picheight=512 screen 0,picwidth,picheight color 0,0,0:boxf 0,0,picwidth,picheight buffer 1:picload picfile,0 originalwidth=ginfo(12) originalheight=ginfo(13) gsel 0 // 1:1 stretchwidth=picwidth stretchheight=picheight if originalwidth>originalheight { //横長 stretchwidth=picwidth stretchheight=(originalheight*picwidth)/originalwidth } if originalwidth<originalheight { //縦長 stretchwidth=(originalwidth*picheight)/originalheight stretchheight=picheight } pos picwidth/2-stretchwidth/2,picheight/2-stretchheight/2:gzoom stretchwidth,stretchheight,1,0,0,originalwidth,originalheight,1



沢渡

リンク

2020/1/25(Sat) 18:17:03|NO.89338

こんな感じでどうでしょうか?
元画像の縦横比と表示領域の縦横比を比べ、元画像が横長か縦長かで場合分けしています。

view_x=400 : view_y=300 //表示領域の横幅・縦幅 buffer 1,1,1 : gsel 1 picload "test.jpg" //ファイル名は適宜変更すること pic_x=ginfo_sx : pic_y=ginfo_sy //元画像の横幅・縦幅 if pic_x*view_y > view_x*pic_y { //本来ならこの式は「pic_x/pic_y > view_x/view_y」とした方が //わかりやすいが、これだと小数点以下が切り捨てられてしまうので変形する。 //元画像が横に広い画像の場合、表示領域の横幅に合わせる pic_x2=view_x pic_y2=view_x*pic_y/pic_x } else { //元画像が縦に広い画像の場合、表示領域の縦幅に合わせる pic_y2=view_y pic_x2=view_y*pic_x/pic_y } gsel 0 color 0,0,0 : boxf 0,0,view_x-1,view_y-1 //表示領域を黒塗り pos (view_x-pic_x2)/2,(view_y-pic_y2)/2 //表示領域にセンタリング表示。左上に合わせるのならpos 0,0で。 gzoom pic_x2,pic_y2,1,0,0,pic_x,pic_y,1



Marksman

リンク

2020/1/25(Sat) 19:16:37|NO.89339

お二人方ありがとうございます。
サンプルを改変させていただいておおよそ形にすることができました。

ただ出来たはいいものの仕組みというか算出式の動きがいまいち理解できません。

stretchheight=(originalheight*picwidth)/originalwidth や pic_x2=view_y*pic_x/pic_y
など、合わせるのにXとYの乗除部分がなぜこう交換するようになっているのか……
そういう公式といわれればそうなのですが



沢渡

リンク

2020/1/25(Sat) 20:37:49|NO.89340


pic_x2=view_y*pic_x/pic_y
これについて説明しますと、
たとえば、元画像の横幅が250で、縦幅が300とした場合、
横幅は縦幅の「6分の5」であることがわかると思います。
この「6分の5」を求めるのが「pic_x/pic_y」という式です。

ここでは縮小後の縦幅はview_yで表されるので、
このview_yに「6分の5」(=pic_x/pic_y)を掛けてやれば、
縮小後の横幅(pic_x2)が求まります。

つまり以上の式は本来、

pic_x2=view_y*(pic_x/pic_y)
とするのが実態に合っているのですが、「pic_x/pic_y」を先に計算してしまうと、
pic_xもpic_yも整数なので、小数点以下が切り捨てられてしまいます。
今回のpic_x=250、pic_y=300を例にとると、
「pic_x/pic_y」の計算結果は0になってしまいます。
そのため、view_y*pic_xを先に計算した上で、pic_yで割っているわけです。



よっぴー

リンク

2020/1/25(Sat) 22:10:26|NO.89341

既に沢渡さんが説明してますが、私のやり方はこんな感じです。

元の画像の横幅をx、縦幅をy、変更後の横幅をa、縦幅をbとします。
横長の場合は、aを最大値として、縦長の場合は、bを最大値にして以下の比例式を作ります。

x:y=a:b
x*b=y*a

元画像が横長の場合は、縦幅を求める必要があるのでb=○○となるように式を変形させます。
b=(y*a)/x

元画像が縦長の場合は、横幅を求める必要があるのでa=○○となるようにします。
a=(x*b)/y

いろいろ文字がありすぎてわかりにくいと思いますが、ざっくりとした説明はこんな感じです。



Marksman

リンク

2020/1/26(Sun) 01:51:26|NO.89342

お二方とも解説ありがとうございます。
なるほど、両方ともちょっとした数学の応用みたいな感じだったんですね。
ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.