• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to Automatically resize a bunch of Logos so they're visually proportional?

Feb 21, 2025 Feb 21, 2025

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?

logos.jpgexpand image

 

TOPICS
How-to , Scripting , Third party plugins

Views

129

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Feb 23, 2025 Feb 23, 2025

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

...

Votes

Translate

Translate
Adobe
Community Expert ,
Feb 21, 2025 Feb 21, 2025

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 21, 2025 Feb 21, 2025

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).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 21, 2025 Feb 21, 2025

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2025 Feb 23, 2025

Copy link to clipboard

Copied

LATEST

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]
            )
    );

};

demo.gifexpand image 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines