How to perfectly fit any image on a fixed size picture control

Post your working scripts, libraries and tools
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to perfectly fit any image on a fixed size picture control

01 Aug 2017, 09:40

@SKAN: Where did you get the maths for the ScaleRect function? Btw is Floor necessary, or can Round be used instead? Because presumably Round would give a marginally closer aspect ratio in some cases.

I've found this quite a tricky issue. Here's my current function (which uses Round):

Code: Select all

;shrink image to fit rectangle (maintain aspect ratio)
JEE_MathsImageFitRectShrink(vImgW, vImgH, vLimW, vLimH, ByRef vImgW3, ByRef vImgH3)
{
	vImgW3 := vImgH3 := ""
	if (vImgW <= vLimW) && (vImgH <= vLimH)
	{
		vImgW3 := vImgW, vImgH3 := vImgH
		return
	}
	vRatioW := vLimW / vImgW ;to fit the image width-wise (although might be too high)
	vRatioH := vLimH / vImgH ;to fit image height-wise (although might be too wide)
	vImgH1 := Round(vImgH * vRatioW) ;vImgW1 := vLimW
	if (vImgH1 <= vLimH)
	{
		vImgW3 := vLimW, vImgH3 := vImgH1
		if (vRatioW > vRatioH)
			return
	}
	vImgW2 := Round(vImgW * vRatioH) ;vImgH2 := vLimH
	if (vImgW2 <= vLimW)
		vImgW3 := vImgW2, vImgH3 := vLimH
	;diagnostic:
	if (vImgW3 = "")
		MsgBox, % "error: " A_ThisFunc "`r`n" "img: " vImgW " " vImgH "`r`n" "lim: " vLimW " " vLimH "`r`n" vImgW1 " " vImgH1 "`r`n" vImgW2 " " vImgH2
}
I also wrote a script to test it:

Code: Select all

q:: ;confirm that JEE_MathsImageFitRectShrink never returns blanks
vOutput := ""
vNum := 51
Loop, % vNum
{
	vLimH := A_Index-1
	Loop, % vNum
	{
		vLimW := A_Index-1
		Loop, % vNum
		{
			vImgH := A_Index-1
			Loop, % vNum
			{
				vImgW := A_Index-1
				;if the function fails, then:
				;a MsgBox within the function should trigger
				JEE_MathsImageFitRectShrink(vImgW, vImgH, vLimW, vLimH, vImgW3, vImgH3)
			}
		}
	}
}
Clipboard := vOutput
MsgBox, % "done"
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SKAN
Posts: 661
Joined: 29 Sep 2013, 16:58

Re: How to perfectly fit any image on a fixed size picture control

01 Aug 2017, 16:00

jeeswg wrote:@SKAN: Where did you get the maths for the ScaleRect function?
I took some help.. 9 years ago from [VxE]
https://autohotkey.com/board/topic/2782 ... ixed-rect/
But there were rounding errors in those functions.
jeeswg wrote:Btw is Floor necessary, or can Round be used instead? Because presumably Round would give a marginally closer aspect ratio in some cases.
The image has to be exact fit at least on one side of the target rect.
So I return one value as is ( either TW or TH ) and only compute the other based on the aspect ratio.
In tricky situations, eg. Source = 256x257 and target = 257x256 I wouldn't want round upwards, hence I went with floor.
OMG! I didn't test the above.. I forgot.

Thanks for sharing your version. I will test it soon.
User avatar
SKAN
Posts: 661
Joined: 29 Sep 2013, 16:58

Re: How to perfectly fit any image on a fixed size picture control

01 Aug 2017, 16:09

Drugwash wrote:I don't think it breaks anything
I think semi transparent pixels are lost... I'm quoting from memory. :)
User avatar
Drugwash
Posts: 751
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania

Re: How to perfectly fit any image on a fixed size picture control

02 Aug 2017, 03:25

… and I was quoting from… hopes. :lol:
Frankly I have no idea. Do you have some specific alternative API set and image to compare the results?

[EDIT]
Unfortunately there is something going on and it's not for the best. I just tested the script with the AHK logo and apparently the blur effect doesn't catch on. it works with the 24bit PNG poster but not with the 32bit alpha-channel PNG logo. Tested both in 98SE and XP (just to be clear).
Last edited by Drugwash on 02 Aug 2017, 10:08, edited 1 time in total.
I've deleted my CloudMe account because of GDPR - the now legal base for privacy invasion and data theft.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to perfectly fit any image on a fixed size picture control

02 Aug 2017, 10:00

I think that in my example, it is OK to use Round (marginally more accurate maintenance of ratio), and not Floor:

Note: we try two possible pairs of values:
W * (LimW/W) = LimW and H * (LimW/W)
W * (LimH/H) and H * (LimH/H) = LimH

start: W, H [both above their limits][where LimW/W > LimH/H]
limits: LimW, LimH
[note: if 'try 1' values too big to fit rectangle, try 'try 2' values]
try 1: LimW, Round(H*(LimW/W)) [bigger than 'try 2' values]
try 2: Round(W*(LimH/H)), LimH [smaller than 'try 1' values]
is Round(W*(LimH/H)) definitely <= LimW? (in which case at least one 'try' would always work)

since W*(LimH/H) <= LimW
so, Round(W*(LimH/H)) <= Round(LimW)
since LimW is an integer, so Round(LimW) = LimW
and so, Round(W*(LimH/H)) <= Round(LimW) = LimW
so, Round(W*(LimH/H)) <= LimW as required

If someone can prove me wrong, or find relevant info for this problem, or generally just find a better more succinct function than mine, that would be most welcome.

@SKAN: Funnily enough when you posted this script, I was thinking about this very problem.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 33 guests