Copy link to clipboard
Copied
I have images that with differnt dimentions, mix with protrait and lanscape, is there any script can detect the image size then auto crop to best fit aspect raio : 1:1, 2:3, 3:4, 4:5, 5:7, 2:1, 3:1 / 3:2, 4:3, 5:4, 7:5, 1:2, 1:)
I tried ask chatGPT to help (LOL), it gave me some messy and cofused code.
Then I did a lot searches, no resources can provide some hints to start to code it.
Any ideas ? Thanks
Copy link to clipboard
Copied
I don’t think I fully understand the process.
Could you post screenshots for an example (what do you start with, what is the intended final result, …)?
Copy link to clipboard
Copied
Thank you, I uploaded 4 files (mixed with protrait and lanscape)
File 1 : 2374*1795, best fit with 4:3 aspect ratio crop
File 2 : 5768*4620, best fit with 5:4 aspect ratio crop
File 3 : 1290*1722, best fit with 3:4 aspect ratio crop
File 4 : 1001*1928, best fit with 1:2 aspect ratio crop
I have over 50 such files with different dimensions in a single folder; I want a script that can auto-detect their sizes and determine to crop them with varying best-fit ratios of aspect, then save them to different folders named 43, 54, 34, 12 and so on........
The images could be in 1:1, 2:3, 3:4, 4:5, 5:7, 2:1, 3:1, 3:2, 4:3, 5:4, 7:5 ratios. Even if I manually crop them, I still need to find out the best-fit aspect ratio many times, so I want automatic this to work.
This script is beyond my ability; any ideas to make it?
Copy link to clipboard
Copied
Why do you list 2:3 and 3:2 and 4:5 and 5:4 etc. separately?
Does this mean that 2:1 and 3:1 are only applicable to landscape and MUST NOT be applied to portrait?
Copy link to clipboard
Copied
Yes, strictly follow the original art image.
Copy link to clipboard
Copied
Once upon a time I was creating program in Python to do similar thing, to determine best available solution. I do not know how to using Javascript. Maybe you can find something already writen in JavaScript for similar purpose and to use it for manual work, at least.
Copy link to clipboard
Copied
File 1 : 2374*1795, best fit with 4:3 aspect ratio crop
File 2 : 5768*4620, best fit with 5:4 aspect ratio crop
File 3 : 1290*1722, best fit with 3:4 aspect ratio crop
File 4 : 1001*1928, best fit with 1:2 aspect ratio crop
By @Calvin21914323wi10
alert("2374*1795 " + get_optimal_crop(2374, 1795));
alert("5768*4620 " + get_optimal_crop(5768, 4620));
alert("1290*1722 " + get_optimal_crop(1290, 1722));
alert("1001*1928 " + get_optimal_crop(1001, 1928));
function get_optimal_crop(w,h)
{
try {
var crops = [[1,1], [1,2], [1,3], [2,3], [3,4], [4,5], [5,7]];
var a0 = 0;
var i0 = 0;
for (var i = 0; i < crops.length; i++)
{
var a = get_area();
if (a0 < a) { a0 = a; i0 = i; }
function get_area()
{
try {
var w1, h1;
if (w > h && crops[i][0] < crops[i][1])
{
var tmp = crops[i][0];
crops[i][0] = crops[i][1];
crops[i][1] = tmp;
}
var w0 = crops[i][0];
var h0 = crops[i][1];
if (w/h < w0/h0)
{
w1 = w;
h1 = Math.round(w*h0/w0);
}
else
{
h1 = h;
w1 = Math.round(h*w0/h0);
}
return w1*h1;
}
catch(e) { throw(e); }
}
}
return crops[i0];
}
catch(e) { throw(e); }
}
Copy link to clipboard
Copied
Tested, I don't know why just no respose at all
Copy link to clipboard
Copied
Tested, I don't know why just no respose at all
By @Calvin21914323wi10
Wikipedia states
»Repose is a word meaning "rest" or "calmness".«
so there might be a typo.
Copy link to clipboard
Copied
Response, I mean. I ran it but nothing happened at all
Copy link to clipboard
Copied
Have you studied, understood, and tried the File > Automate > Fit Image... script and is it not what you want...?
If it only works for some photos, you could indeed write a script that uses a different Fit Image... depending on sizes or ratios the script detects — or just do them in separate batches.
PS: Fit Image will use the Image Interpolation set in Preferences.
Copy link to clipboard
Copied
BTW, you can also use Conditional steps, so you don't necessarily need your own script.
Copy link to clipboard
Copied
There are different algorithms to determine aspect ratios, the following code uses 3 different ones:
/*
Photoshop Document Dimensions - MP Value - Aspect Ratio.jsx
v1.0, Stephen Marsh 13th February 2022
*/
#target photoshop
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var w = app.activeDocument.width.value;
var h = app.activeDocument.height.value;
var r = gcd(w, h);
var mp = w * h / 1000000;
var pix = w * h;
var ppiRes = app.activeDocument.resolution;
var ppcmRes = ppiRes / 2.54;
var ratio = w / h;
var docName = app.activeDocument.name;
var wMetric = w / 72 * 2.54;
var hMetric = h / 72 * 2.54;
var wInches = w / 72;
var hInches = h / 72;
var doc = app.activeDocument;
var w = doc.width.value;
var h = doc.height.value;
alert(
'Document Info' + '\n' +
'Document Name: ' + docName + '\n' +
'Dimensions: ' + w + ' x ' + h + ' pixels' + '\n' +
'Dimensions: ' + Math.round(wMetric * 100) / 100 + ' x ' + Math.round(hMetric * 100) / 100 + ' cm / ' + Math.round(wInches * 1000) / 1000 + ' x ' + Math.round(hInches * 1000) / 1000 + ' inches' + '\n' +
'Resolution: ' + Math.round(ppiRes * 10) / 10 + ' ppi / ' + Math.round(ppcmRes * 1000) / 1000 + ' ppcm' + '\n' +
'Megapixel Value: ' + Math.round(mp * 10) / 10 + ' MP' + ' (' + pix + ' pixels)' + '\n' +
'Aspect Ratio:' + '\n' + ratio.toFixed(2) + ':1' + ' / ' + ratio.toFixed(2) * 2 + ':2 / ' + ratio.toFixed(2) * 4 + ':4' + ' (Basic)' + '\n' +
w / r + ':' + h / r + ' (GCD)' + '\n' +
aspect_ratio(w / h, 50).toString().replace(',', ':') + ' (Farey)'
);
app.preferences.rulerUnits = savedRuler;
function gcd(a, b) {
/* https://stackoverflow.com/questions/1186414/whats-the-algorithm-to-calculate-aspect-ratio-i-need-an-output-like-43-169 */
return (b == 0) ? a : gcd(b, a % b);
}
function aspect_ratio(val, lim) {
var lower = [0, 1];
var upper = [1, 0];
while (true) {
var mediant = [lower[0] + upper[0], lower[1] + upper[1]];
if (val * mediant[1] > mediant[0]) {
if (lim < mediant[1]) {
return upper;
}
lower = mediant;
} else if (val * mediant[1] == mediant[0]) {
if (lim >= mediant[1]) {
return mediant;
}
if (lower[1] < upper[1]) {
return lower;
}
return upper;
} else {
if (lim < mediant[1]) {
return lower;
}
upper = mediant;
}
}
}
Adobe Bridge has a filter for aspect ratio, which you can use to open all files in a folder with the same ratio... But you would have to determine the threshold and fuzziness as to what matches what.
Copy link to clipboard
Copied
Thank you very much, will test in my images.
Copy link to clipboard
Copied
For your "1_43.jpg" sample, Bridge lists the aspect ratio as 3:4, however you would class this as 4:3 as it is landscape.
My script reports the following for the same image:
Aspect Ratio:
1.32:1 / 2.64:2 / 5.28:4 (Basic)
2374:1795 (GCD)
41:31 (Farey)
So the Farey formula is closest to Bridge in this case with rounding, but the GCD formula is better from memory in other cases.
I don't know if there is a single "best" formula. Math isn't my strong point, I had to adapt various JS codes for Photoshop.
Copy link to clipboard
Copied
Tested, it can detect and show information but not crop the image
Copy link to clipboard
Copied
Tested, it can detect and show information but not crop the image
By @Calvin21914323wi10
One can crop both via DOM- and AM-code so what is giving you problems?
Copy link to clipboard
Copied
Yes, I tried run in action, no crop, then I added my own crop function, still not work, maybe I am too stupid to code
Copy link to clipboard
Copied
Tested, it can detect and show information but not crop the image
By @Calvin21914323wi10
That is correct, the solution isn't handed to you on a silver platter!
Before one can even think about cropping, a suitable aspect ratio detection method has to be found, and then you have to determine some sort of pass/fail threshold tolerance etc.
Copy link to clipboard
Copied
Thank you, but even the best one - Farey, still not give out a exact ratio e.g.File 4 - best fit is 1:2, but it gave 13:25 very accurate but not a POPULAR RATIO (SELLERABLE PRINT SIZE RATIO), I hope you understand what I want to say.
Now I am trying use excel find my algorithm, but found many weird ratio in my collection, scratching my head and try to do more market research
Copy link to clipboard
Copied
Indeed, these are the challenges.
Have you looked at the Adobe Bridge aspect ratio filter?
Copy link to clipboard
Copied
Does this provide meaningful results?
// determine closest ratio from a limited set;
// 2023, use at your own risk;
if (app.documents.length > 0) {
app.togglePalettes();
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = activeDocument;
var theW = myDocument.width;
var theH = myDocument.height;
var theProportion = theW/theH;
var theProportions = [[2,3], [5,7], [3,4], [4,5], [1,1], [5,4], [4,3], [7,5], [3,2], [2,1], [3,1]];
var theResult = theProportions.sort(sortArrayByDifference)[0];
var thisProp = theResult[0]/theResult[1];
if (theProportion < thisProp) {
var targetW = theW;
var targetH = theW*theResult[1]/theResult[0];
}
else {
var targetW = theH*theResult[0]/theResult[1];
var targetH = theH;
};
alert ("at the aspect ratio "+theResult.join("/")+" the image would be\n"+targetW+" x "+targetH);
app.preferences.rulerUnits = originalRulerUnits;
app.togglePalettes();
};
////// sort by difference to a number //////
function sortArrayByDifference(a,b) {
if (Math.abs((a[0]/a[1])-theProportion)<Math.abs((b[0]/b[1])-theProportion)) return -1;
if (Math.abs((a[0]/a[1])-theProportion)>Math.abs((b[0]/b[1])-theProportion)) return 1;
return 0;
};
Copy link to clipboard
Copied
Thank you very much, it works
I added
app.activeDocument.crop.........
and it works, thanks again
Copy link to clipboard
Copied
Thank you very much, it works
I added
app.activeDocument.crop.........
and it works, thanks again
By @Calvin21914323wi10
Please share the final code, I for one would be interested.
EDIT:
https://theiviaxx.github.io/photoshop-docs/Photoshop/Document/crop.html
Copy link to clipboard
Copied
Thanks to @c.pfaffenbichler , I added 2 lines only
if (app.documents.length > 0) {
app.togglePalettes();
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = activeDocument;
var theW = myDocument.width;
var theH = myDocument.height;
var theProportion = theW/theH;
var theProportions = [[1,3],[1,2],[2,3], [5,7], [3,4], [4,5], [1,1], [5,4], [4,3], [7,5], [3,2], [2,1], [3,1]];
var theResult = theProportions.sort(sortArrayByDifference)[0];
var thisProp = theResult[0]/theResult[1];
if (theProportion < thisProp) {
var targetW = theW;
var targetH = theW*theResult[1]/theResult[0];
}
else {
var targetW = theH*theResult[0]/theResult[1];
var targetH = theH;
};
var bounds = [0,0,targetW, targetH]
alert ("at the aspect ratio "+theResult.join("/")+" the image would be\n"+targetW+" x "+targetH);
app.activeDocument.crop(bounds);
app.preferences.rulerUnits = originalRulerUnits;
app.togglePalettes();
};
////// sort by difference to a number //////
function sortArrayByDifference(a,b) {
if (Math.abs((a[0]/a[1])-theProportion)<Math.abs((b[0]/b[1])-theProportion)) return -1;
if (Math.abs((a[0]/a[1])-theProportion)>Math.abs((b[0]/b[1])-theProportion)) return 1;
return 0;
};