Copy link to clipboard
Copied
I need a way to change the size of the logo so that they look proportional next to each other.
If I use one height or width for every individual logo, some logos are large and some are too small..
is there maybe a script for this or plugin? Is resizing them by hand really the only way?
 
1 Correct answer
Hi @optimisticperson, as others have rightly said, there is no other way than adjusting by hand because Illustrator has no capability to judge properties such as the "visual weight" of an object. No doubt one day it will! Making disparate logos sit comfortably together is a task involving significant skill.
However, perhaps it would still save some time to give a rough approximation? I have written a script that scales the selected page items such that the area of each item's bounds matches th
...Explore related tutorials & articles
Copy link to clipboard
Copied
Things 'looking proportional' is subjective. If you want a particular measurement on each logo to relate to some fixed value then perhaps a script can help, but a script can't adjust things by eye for you.
Copy link to clipboard
Copied
Optimistic,
I agree with Doug, of course. My own first thought was that the best way would be to scale the original logo sizes in comparable use (not one from a poster/billboard and one from a business card) by the same factor (or leave them as they are), with exceptions that can be dealt with individually (and must in any case).
Copy link to clipboard
Copied
When you say proportional you are talking about a visual balance. In that case, you will have to do each individually to get the aesthetic look that you want. If you do it dimensionally, they will continue to look unbalanced.
Copy link to clipboard
Copied
Hi @optimisticperson, as others have rightly said, there is no other way than adjusting by hand because Illustrator has no capability to judge properties such as the "visual weight" of an object. No doubt one day it will! Making disparate logos sit comfortably together is a task involving significant skill.
However, perhaps it would still save some time to give a rough approximation? I have written a script that scales the selected page items such that the area of each item's bounds matches the average area of all the items.
It won't do a great job, because the bounds of a logo isn't a good metric for the visual weight, but it might provide a starting point. Let me know if it is helpful.
- Mark
/**
* @file Scale To Average Area.js
*
* Scales the selection such that the area
* of each item's geometric bounds match
* the average area of the selected items.
*
* @author m1b
* @version 2025-02-24
* @discussion https://community.adobe.com/t5/illustrator-discussions/how-to-automatically-resize-a-bunch-of-logos-so-they-re-visually-proportional/m-p/15168811
*/
(function () {
var doc = app.activeDocument,
items = doc.selection;
if (0 === items.length)
return alert('Please select some items and try again.');
scaleItemsToAverageArea(items);
})();
/**
* Scales each page item in `items` such that the area
* of each item's geometric bounds match the average area
* of the selected items.
* @date 2025-02-24
* @param {Array<PageItem>} items - the items to scale.
*/
function scaleItemsToAverageArea(items) {
var areas = [],
areaSum = 0;
for (var i = 0, bounds, area; i < items.length; i++) {
bounds = getItemBoundsIllustrator(items[i], false);
area = (bounds[2] - bounds[0]) * -(bounds[3] - bounds[1]);
areas[i] = area;
areaSum += area;
}
var averageArea = Math.sqrt(areaSum) / items.length;
for (var i = 0, scaleFactor; i < areas.length; i++) {
scaleFactor = averageArea / Math.sqrt(areas[i]);
items[i].resize(scaleFactor * 100, scaleFactor * 100);
}
};
/**
* Returns bounds of item(s).
* @author m1b
* @version 2024-03-10
* @param {PageItem|Array<PageItem>} item - an Illustrator PageItem or array of PageItems.
* @param {Boolean} [geometric] - if false, returns visible bounds.
* @param {Array} [bounds] - private parameter, used when recursing.
* @returns {Array} - the calculated bounds.
*/
function getItemBoundsIllustrator(item, geometric, bounds) {
var newBounds = [],
boundsKey = geometric ? 'geometricBounds' : 'visibleBounds';
if (undefined == item)
return;
if (
item.typename == 'GroupItem'
|| item.constructor.name == 'Array'
) {
var children = item.typename == 'GroupItem' ? item.pageItems : item,
contentBounds = [],
isClippingGroup = (item.hasOwnProperty('clipped') && item.clipped == true),
clipBounds;
for (var i = 0, child; i < children.length; i++) {
child = children[i];
if (
child.hasOwnProperty('clipping')
&& true === child.clipping
)
// the clipping item
clipBounds = child.geometricBounds;
else
contentBounds.push(getItemBoundsIllustrator(child, geometric, bounds));
}
newBounds = combineBounds(contentBounds);
if (isClippingGroup)
newBounds = intersectionOfBounds([clipBounds, newBounds]);
}
else if (
'TextFrame' === item.constructor.name
&& TextType.AREATEXT !== item.kind
) {
// get bounds of outlined text
var dup = item.duplicate().createOutline();
newBounds = dup[boundsKey];
dup.remove();
}
else if (item.hasOwnProperty(boundsKey)) {
newBounds = item[boundsKey];
}
// `bounds` will exist if this is a recursive execution
bounds = (undefined == bounds)
? bounds = newBounds
: bounds = combineBounds([newBounds, bounds]);
return bounds;
};
/**
* Returns the combined bounds of all bounds supplied.
* Works with Illustrator or Indesign bounds.
* @author m1b
* @version 2024-03-09
* @param {Array<bounds>} boundsArray - an array of bounds [L, T, R, B] or [T, L , B, R].
* @returns {bounds?} - the combined bounds.
*/
function combineBounds(boundsArray) {
var combinedBounds = boundsArray[0],
comparator;
if (/indesign/i.test(app.name))
comparator = [Math.min, Math.min, Math.max, Math.max];
else
comparator = [Math.min, Math.max, Math.max, Math.min];
// iterate through the rest of the bounds
for (var i = 1; i < boundsArray.length; i++) {
var bounds = boundsArray[i];
combinedBounds = [
comparator[0](combinedBounds[0], bounds[0]),
comparator[1](combinedBounds[1], bounds[1]),
comparator[2](combinedBounds[2], bounds[2]),
comparator[3](combinedBounds[3], bounds[3]),
];
}
return combinedBounds;
};
/**
* Returns the overlapping rectangle
* of two or more rectangles.
* NOTE: Returns undefined if ANY
* rectangles do not intersect.
* @author m1b
* @version 2024-09-05
* @param {Array<bounds>} arrayOfBounds - an array of bounds [L, T, R, B] or [T, L , B, R].
* @returns {bounds?} - intersecting bounds.
*/
function intersectionOfBounds(arrayOfBounds) {
var comparator;
if (/indesign/i.test(app.name))
comparator = [Math.max, Math.max, Math.min, Math.min];
else
comparator = [Math.max, Math.min, Math.min, Math.max];
// sort a copy of array
var bounds = arrayOfBounds
.slice(0)
.sort(function (a, b) { return b[0] - a[0] || a[1] - b[1] });
// start with first bounds
var intersection = bounds.shift(),
b;
// compare each bounds, getting smaller
while (b = bounds.shift()) {
// if doesn't intersect, bail out
if (!boundsDoIntersect(intersection, b))
return;
intersection = [
comparator[0](intersection[0], b[0]),
comparator[1](intersection[1], b[1]),
comparator[2](intersection[2], b[2]),
comparator[3](intersection[3], b[3]),
];
}
return intersection;
};
/**
* Returns true if the two bounds intersect.
* @author m1b
* @version 2024-03-10
* @param {Array} bounds1 - bounds array.
* @param {Array} bounds2 - bounds array.
* @param {Boolean} [TLBR] - whether bounds arrays are interpreted as [t, l, b, r] or [l, t, r, b] (default: based on app).
* @returns {Boolean}
*/
function boundsDoIntersect(bounds1, bounds2, TLBR) {
if (undefined == TLBR)
TLBR = (/indesign/i.test(app.name));
return !(
TLBR
// TLBR
? (
bounds2[0] > bounds1[2]
|| bounds2[1] > bounds1[3]
|| bounds2[2] < bounds1[0]
|| bounds2[3] < bounds1[1]
)
// LTRB
: (
bounds2[0] > bounds1[2]
|| bounds2[1] < bounds1[3]
|| bounds2[2] < bounds1[0]
|| bounds2[3] > bounds1[1]
)
);
};

