Help with Math for Area Calculations

Guilty of bunking off double maths on monday mornings and now need help. Im trying to set the long edge of a fixed aspect rectangle to = defined area. I have all the photoshop processes run without issue it’s just my maths thats letting me down. This is just the math parts as I have them but its working off area relationship to long edge only. I hope I’ve explained this correctly?

property ImageArea : 1000 -- Square Root of Target Image Area in Pixels (1 mega-pixel for test)
--
set docHeight to 6000 -- To be defined by Photoshop at run time
set docWidth to 1500 -- To be defined by Photoshop at run time
--
set ThisImageArea to docHeight * docWidth
set ThisImageArea to SqRoot(ThisImageArea) of me
set AreaPro to (ThisImageArea / ImageArea) -- This is Area
if (docHeight ≥ docWidth) then
	set AspectRatio to (docHeight / docWidth) -- I think I need to use this some how?
	set imageheight to (docHeight / AreaPro) as string -- close but no cigar!!
	display dialog imageheight
else
	set AspectRatio to (docWidth / docHeight) -- I think I need to use this some how?
	set imagewidth to (docWidth / AreaPro) as string
	display dialog imagewidth
end if
--
on SqRoot(ThisImageArea)
	return ThisImageArea ^ 0.5
end SqRoot

However you’d like to do it, these relationships apply:

Area_oi = H_oi * W_oi [_oi is original image]
AspRatio = H_oi/W_oi
so
H_oi = AspRatio * W_oi
and
Area_oi = AspRatio * (W_oi ^ 2)
thus
W_oi = sqRt(Area_oi / AspRatio)
If we want to reduce the area by a factor of K then
K = Area_oi/Area_ni [_ni is new image]
W_ni = (Area_ni / (AspRatio * K)) ^ 0.5
H_ni = AspRatio * W_ni

I know you can deal with it from there. I know you don’t need help with AppleScript

Adam, thanks for the math lesson I had a feeling this was your bag seem to recall being math teacher or something to that effect? any how I have faith in your formula and will try to implement it in my script. I should then be able to define several image sizes as properties. I reckon with Photoshop’s rounding to the pixel I should be within + or -1 x longest edge which will be more than close enough thanks very much.

Mechanical Engineering Professor at SUNY@B, MIT, then here in Halifax, Head of ME Department, then Dean of Eng, and then Principal of the College, in fact. If you have problems with it, don’t hesitate.

Adam, I’ve had a look at this but appear to be going wrong with the formula some where. What Im getting when I test is the aspect ratio maintained but the long edge is to square root new image area so if say for instance aspect ratio is 2:1 then the new image area is half what I wanted. I dont think I had made myself very clear in the first post. Here is what I was using so you can check if I did something wrong.

property ImageArea : 1000000 -- NI Area (No longer as SqRt)
--
set docHeight to 1000 -- OI Height
set docWidth to 2000 -- OI Width
set ThisImageArea to docHeight * docWidth --OI Area
set AspectRatio to (docHeight / docWidth) --OI AR
--
set AreaPro to (ThisImageArea / ImageArea) -- K
--
set imagewidth to ((ImageArea / (AspectRatio * AreaPro)) ^ 0.5) as string
set imageheight to (AspectRatio * imagewidth) as string
display dialog imageheight & " x " & imagewidth
--

Wrong area in formula - you want to reduce the original. This works:


property ImageArea : 1000000 -- NI Area (No longer as SqRt)
--
set docHeight to 1000 -- OI Height
set docWidth to 2000 -- OI Width
set ThisImageArea to docHeight * docWidth -- OI Area
set AspectRatio to (docHeight / docWidth) -- OI AR
--
set AreaPro to (ThisImageArea / ImageArea) -- K
--
set imagewidth to ((ThisImageArea / (AspectRatio * AreaPro)) ^ 0.5) as string
set imageheight to (AspectRatio * imagewidth) as string

display dialog imageheight & " x " & imagewidth & return & return & "New Area Check: = " & imageheight * imagewidth
--

If you don’t need the intermediate variables (I don’t know what you’re trying to achieve), then this is much simpler:


property ImageArea : 1000000 -- New Area
--
set docHeight to 1000 -- OI Height
set docWidth to 2000 -- OI Width
--
set imagewidth to ((docWidth * ImageArea / docHeight) ^ 0.5) as string
set imageheight to (docHeight * imagewidth / docWidth) as string

display dialog imageheight & " x " & imagewidth & return & return & "New Area Check: = " & imageheight * imagewidth
--

Adam, what I was trying to achieve was a method of sizing down raw images that are large files from our digital studio to several file sizes for differing uses. Photoshop will not let me save file to a given file size but I can pretty much sort this based on a pixel area calculation if Im making myself clear. The images are all product shots with paths, the image is processed to trim just outside of this path so all the images are of irregular size. The paths for these are now being out-sourced I already have some code to check these, after that what I was hoping to do was specify 3 or so ImageArea properties at the beginning to base the script off. I do not need any of the “intermediate variables” your new formula works exactly as I wanted. Thank you very much

I understand. This is prettier:


property ImageArea : 1000000 -- New Area
--
set docHeight to 1500 -- OI Height
set docWidth to 2500 -- OI Width
--
set imagewidth to ((docWidth * ImageArea / docHeight) ^ 0.5)
set imageheight to (docHeight * imagewidth / docWidth)

display dialog "" & (round imageheight) & " x " & (round imagewidth) & return & return & "New Area Check: = " & ((imageheight * imagewidth) as integer)
--

Adam, its in and running in some small tests and now works exactly as I had wished. It’s going to be run each week to deal with several hundred images and there pretty large files. Thats why I had concerns over my math as an error could produce some monster files. It’s all part of a Photoshop script that requires some piecing together but in short this is how Im using it within some loops.

property ImageArea1 : 6000000 -- 6 megaPixel
property ImageArea2 : 3000000 -- 3 megaPixel
property ImageArea3 : 1000000 -- 1 megaPixel
--
set docHeight to 1500 -- To be defined by Photoshop at run time
set docWidth to 2500 -- To be defined by Photoshop at run time
--
set imagewidth to ((docWidth * ImageArea1 / docHeight) ^ 0.5)
set imageheight to (docHeight * imagewidth / docWidth)
--
set imagewidth to ((docWidth * ImageArea2 / docHeight) ^ 0.5)
set imageheight to (docHeight * imagewidth / docWidth)
--
set imagewidth to ((docWidth * ImageArea3 / docHeight) ^ 0.5)
set imageheight to (docHeight * imagewidth / docWidth)

I was thinking too much on wether the image was portrait or landscape when in “math” using the correct formula it does not matter.

Now I can’t paste between the blocks doh

I’m not PhotoShop aware, so can’t help you there.

Adam, sorry it was me being a muppet my edit was to correct the fact that my code paste had not gone between the "

" & "

" things. Here is what I have so far needs some more work but Im pretty pleased with this so far.

property ImageArea1 : 6000000 -- 6 megaPixel
property ImageArea2 : 3000000 -- 3 megaPixel
property ImageArea3 : 1000000 -- 1 megaPixel
--
set inputFolder to choose folder with prompt "Where are the Images?" without invisibles
set TodaysDate to do shell script "date \"+%d-%m-%y\""
--
tell application "Finder"
	set filesList to files in inputFolder
	set ResizedImages to make new folder at desktop with properties ¬
		{name:"Resized Images " & TodaysDate}
	set LargeImages to make new folder at ResizedImages with properties ¬
		{name:"Large Images"}
	set MediumImages to make new folder at ResizedImages with properties ¬
		{name:"Medium Images"}
	set SmallImages to make new folder at ResizedImages with properties ¬
		{name:"Small Images"}
	set MediumGrayImages to make new folder at ResizedImages with properties ¬
		{name:"Medium GrayScale Images"}
	set SmallGrayImages to make new folder at ResizedImages with properties ¬
		{name:"Small GrayScale Images"}
end tell
--
tell application "Adobe Photoshop CS"
	set display dialogs to never
	set UserPrefs to properties of settings
	set ruler units of settings to pixel units
end tell
--
repeat with aFile in filesList
	set fileIndex to 0
	tell application "Finder"
		set theFile to aFile as alias
		set theFileName to name of theFile
	end tell
	tell application "Adobe Photoshop CS"
		activate
		open theFile
		set docRef to the current document
		tell docRef
			set docName to name of docRef
			set docBaseName to getBaseName(docName) of me
			if (bits per channel of docRef is sixteen) then
				set bits per channel of docRef to eight
			end if
			if (mode of docRef is not CMYK) then
				change mode docRef to CMYK
			end if
			delete (every channel whose kind is not component channel)
			if (count of art layers) > 1 or (count of layer sets) > 0 or ((count of art layers) is 1 and not background layer of layer 1) then flatten
			if exists (path item 1) then
				set thepath to name of path item 1
				set subpaths to count of sub path items of path item 1
				set openPaths to (count of (sub path items whose closed is false) of path item 1) as string
				set thepoints to 0
				repeat with x from 0 to (subpaths - 1) -- Java's index starts at "0" Zero
					do javascript "activeDocument.pathItems[0].subPathItems[" & x & "].pathPoints.length" show debugger on runtime error
					set pathpoints to the result as string
					set thepoints to thepoints + pathpoints as string
				end repeat
				make clipping path path item 1 flatness 0.3
				create selection path item 1 feather amount 0 with antialiasing
				expand selection by 10
				invert selection
				fill selection with contents {class:RGB color, red:255, green:255, blue:255}
				deselect
				trim basing trim on top left pixel
			else
				set thepath to "No Clipping Path"
				set thepoints to "0"
				set openPaths to "0"
			end if
			writelog(docName, thepath, openPaths, thepoints) of me
			--
			set docHeight to height of docRef
			set docWidth to width of docRef
			set savedState to current history state of docRef
			--
			set imagewidth to ((docWidth * ImageArea1 / docHeight) ^ 0.5) as string
			set imageheight to (docHeight * imagewidth / docWidth) as string
			resize image height imageheight width imagewidth resolution 300
			set newFileName to (LargeImages as string) & docBaseName
			save docRef in file newFileName as Photoshop EPS with options ¬
				{class:EPS save options, embed color profile:true, encoding:binary, preview type:eight bit TIFF} ¬
					appending lowercase extension with copying
			set current history state of docRef to savedState
			--
			set imagewidth to ((docWidth * ImageArea2 / docHeight) ^ 0.5) as string
			set imageheight to (docHeight * imagewidth / docWidth) as string
			resize image height imageheight width imagewidth resolution 300
			set newFileName to (MediumImages as string) & docBaseName
			save docRef in file newFileName as Photoshop EPS with options ¬
				{class:EPS save options, embed color profile:true, encoding:binary, preview type:eight bit TIFF} ¬
					appending lowercase extension with copying
			--
			change mode docRef to grayscale
			set newFileName to (MediumGrayImages as string) & docBaseName
			save docRef in file newFileName as Photoshop EPS with options ¬
				{class:EPS save options, embed color profile:true, encoding:binary, preview type:eight bit TIFF} ¬
					appending lowercase extension with copying
			set current history state of docRef to savedState
			--
			set imagewidth to ((docWidth * ImageArea3 / docHeight) ^ 0.5) as string
			set imageheight to (docHeight * imagewidth / docWidth) as string
			resize image height imageheight width imagewidth resolution 200
			set newFileName to (SmallImages as string) & docBaseName
			save docRef in file newFileName as Photoshop EPS with options ¬
				{class:EPS save options, embed color profile:true, encoding:binary, preview type:eight bit TIFF} ¬
					appending lowercase extension with copying
			--
			change mode docRef to grayscale
			set newFileName to (SmallGrayImages as string) & docBaseName
			save docRef in file newFileName as Photoshop EPS with options ¬
				{class:EPS save options, embed color profile:true, encoding:binary, preview type:eight bit TIFF} ¬
					appending lowercase extension with copying
		end tell
		close current document without saving
	end tell
end repeat
--
tell application "Adobe Photoshop CS"
	set ruler units of settings to ruler units of UserPrefs
end tell
--
set ReadFile to ((path to desktop folder) as text) & "Path Point Log.txt" as alias
tell application "TextEdit"
	activate
	open ReadFile
end tell
--
on getBaseName(fName)
	set baseName to fName
	repeat with idx from 1 to (length of fName)
		if (item idx of fName = ".") then
			set baseName to (items 1 thru (idx - 1) of fName) as string
			exit repeat
		end if
	end repeat
	return baseName
end getBaseName
--
on writelog(docName, thepath, openPaths, thepoints)
	set theLog to ((path to desktop folder) as text) & "Path Point Log.txt"
	try
		open for access file the theLog with write permission
		write (return & docName & " - " & thepath & " - " & thepoints & " Points - Open Sub Paths " & openPaths) to file the theLog starting at eof
		close access file the theLog
	on error
		try
			close access file the theLog
		end try
	end try
end writelog
--

What I mean’t to say was the things when you press the “Applescript” button. I tried to quote them and it buggered up oh I have a long way to go yet!!! Have a good weekend. where do I send the cigar? I was close ish but you were on the money!