Automate Resize and Crop for objects?

New Here ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

Hello! I have 1000 bag photos and when I crop them, one bag looks big and the other small. How can I make each one aligned and the same size as in the example? Has anyone done something like this before? I want the product photos to look compatible with each other.Ekran Resmi 2022-06-16 19.43.13.png

TOPICS
Actions and scripting , macOS

Views

138

Likes

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
Adobe Community Professional ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

You might get somewhat consistent results using a script, maybe an action, where you use something like select subject then use the selection bounding box to adjust the crop around that bounding box.

Likes

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
New Here ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

Thank you! I don't want select subject because some details of the bag can be lost. Can you send me example video?

Likes

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
Enthusiast ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

Select Subject is not meant to cut it out here (I think?), but to establish where the subject is.

For example, you could use Edit > Crop after (in theory), but this too may cut off stuff you want to keep. So the trick is to first enlarge the selection, for example. You could do this with Select > Transform Selection (to a safer distance), then use Edit > Crop.  You might find a way to do it exactly right w/o even needing a script. Key is often to record it with the ruler set to %.
-

Watch the toolbar you get when Transform Selection is active. You can probaby set the width to, for example, 300% so you are sure to keep the width of your photo when using Edit > Crop, and adjust the vertical % to what you like. As you can use % here, you probably don't even need the ruler set to % for anything.

Likes

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
Enthusiast ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

Basically, I think this can work. If your bags are wildly different in heigth, you should batch intelligently though (batches of similar size).

(1) Select Subject

(2) Select > Transform Selection

If all bags are somewhat the same size, pick a percentage for Hor and Ver that creates the distance that you want. If you want to keep the full width of your photo for some reason, specify a horizontal % that exceeds the width in all cases — for example: 300%)

(3) Edit > Crop

AFAIK, this should crop exactly to the bounds of the selection, but it seems to leave a small amount of extra space if there is some feathering involved somehow.

(4) Deselect

-
What you could add after that (in short)...

- Fit Image to a size that you picked for all similarly-sized bags

- Enlarge Canvas to your final dimensions

- Align bag to some spot you prefer

egq4NjnPHz.jpg

(Transform specifies 300% here, which I now think is not the best idea)

Likes

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
Adobe Community Professional ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

As others have mentioned. Select subject is just to get the basic position and size of the bag. Then using the bounds of that selection, expand the crop to to degree that it gives you the boarder you want.

Likes

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
Enthusiast ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

Here's an example action:

https://www55.zippyshare.com/v/VCHQN2t0/file.html

-

Adapt all formatting to your needs.

To re-record the final "Move current layer" positioning step, first set your ruler to percent, click record and with the Move tool drag the bag into position (hold shift to move in one direction only).

QOifshTOgY.jpg

Likes

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
Enthusiast ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

If not all are nicely level, you could output two versions (or more), some on which you've applied one of the ACR Geometry auto modes on.

Chuck's idea is good. If you want your crop to be larger than the selection (both for composition and to be safe), record dragging the crop larger while your ruler is set to percent. The action will remember that and do it similarly no matter the size of the photo. Then finally, you do a Fit Image to the smallest format you are using (or smaller), and hopefully those all line up well enough.

-

Edit > Trim... and Edit > Crop might be useful too maybe.

Likes

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
Adobe Community Professional ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

Although the following link had people as the subject, however, it may also work with your images if select subject can make a consistent, rough selection of the main object. In addition, if there is good contrast between the bag and the background then you can use this to create a selection as a base start point for expansion before cropping:

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-help-crop-based-on-select-subj...

 

Example original images would help to work out the automation, as well as the final results at the correct final size. Is this for print or web/screen display (I'm guessing the latter)?

Likes

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
Adobe Community Professional ,
Jun 16, 2022 Jun 16, 2022

Copy link to clipboard

Copied

You can use this script as a base for positioning layers (it uses the select Subject function to determine object boundaries).

This script works with layers. The sample size is the bottom layer (it doesn't have to be a photo, you can just draw a square of the desired size).

 

#target photoshop
var lr = new AM('layer'),
    doc = new AM('document');
activeDocument.suspendHistory('Align and fit subjects', 'alignAndFit()')
function alignAndFit() { app.doProgress('', 'main ()') }
function main() {
    var targets = [],
        targetIds = doc.getProperty('targetLayersIDs');
    app.updateProgress(1, 2)
    for (var i = 0; i < targetIds.count; i++) {
        doc.selectLayer(id = targetIds.getReference(i).getIdentifier('layerID'))
        app.changeProgressText('Find object bounds: ' + lr.getProperty('name', false, id))
        lr.autoCutout();
        if (doc.hasProperty('selection')) {
            var subject = doc.descToObject(doc.getProperty('selection'))
            lr.deselect()
            with (subject) {
                subject.width = right - left
                subject.height = bottom - top
                subject.center = { y: top + height / 2, x: left + width / 2 }
                subject.vertical = bottom - top > right - left
            }
            subject.id = id
            targets.push(subject)
        }
    }
    app.updateProgress(2, 2)
    if (targets.length > 1) {
        sample = targets.shift()
        for (var i = 0; i < targets.length; i++) {
            lr.selectLayer(targets[i].id)
            app.changeProgressText('Align layer: ' + lr.getProperty('name', false, targets[i].id))
            lr.transform(sample.center.x - targets[i].center.x, sample.center.y - targets[i].center.y,
                sample.vertical ? sample.width / targets[i].width * 100 : sample.height / targets[i].height * 100,
                targets[i].center.x, targets[i].center.y)
        }
    }
}
function AM(target, order) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;
    target = s2t(target)
    this.getProperty = function (property, descMode, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
        return descMode ? executeActionGet(r) : getDescValue(executeActionGet(r), property)
    }
    this.hasProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
            : r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
        return executeActionGet(r).hasKey(property)
    }
    this.descToObject = function (d) {
        var o = {}
        for (var i = 0; i < d.count; i++) {
            var k = d.getKey(i)
            o[t2s(k)] = getDescValue(d, k)
        }
        return o
    }
    this.selectLayer = function (id, add) {
        add = (add == undefined) ? add = false : add;
        (r = new ActionReference()).putIdentifier(s2t('layer'), id);
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        if (add) { d.putEnumerated(s2t('selectionModifier'), s2t('selectionModifierType'), s2t('addToSelection')) }
        d.putBoolean(s2t('makeVisible'), false)
        executeAction(s2t('select'), d, DialogModes.NO)
    }
    this.deselect = function () {
        (r = new ActionReference()).putProperty(s2t('channel'), s2t('selection'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('to'), s2t('ordinal'), s2t('none'));
        executeAction(s2t('set'), d, DialogModes.NO);
    }
    this.autoCutout = function (sampleAllLayers) {
        sampleAllLayers = sampleAllLayers == undefined ? false : true;
        (d = new ActionDescriptor()).putBoolean(s2t('sampleAllLayers'), sampleAllLayers);
        executeAction(s2t('autoCutout'), d, DialogModes.NO);
    }
    this.transform = function (dX, dY, scale, x, y) {
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSIndependent"));
        ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x);
        d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y);
        d.putObject(s2t('position'), s2t('paint'), d1);
        (d2 = new ActionDescriptor()).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), dX);
        d2.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), dY);
        d.putObject(s2t('offset'), s2t('offset'), d2);
        d.putUnitDouble(s2t('width'), s2t('percentUnit'), scale);
        d.putUnitDouble(s2t('height'), s2t('percentUnit'), scale);
        d.putEnumerated(s2t('interfaceIconFrameDimmed'), s2t('interpolationType'), s2t('bicubic'));
        executeAction(s2t('transform'), d, DialogModes.NO);
    }
    function getDescValue(d, p) {
        switch (d.getType(p)) {
            case DescValueType.OBJECTTYPE: return (d.getObjectValue(p));
            case DescValueType.LISTTYPE: return d.getList(p);
            case DescValueType.REFERENCETYPE: return d.getReference(p);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
            case DescValueType.STRINGTYPE: return d.getString(p);
            case DescValueType.INTEGERTYPE: return d.getInteger(p);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
            case DescValueType.DOUBLETYPE: return d.getDouble(p);
            case DescValueType.ALIASTYPE: return d.getPath(p);
            case DescValueType.CLASSTYPE: return d.getClass(p);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
            case DescValueType.ENUMERATEDTYPE: return [t2s(d.getEnumerationType(p)), t2s(d.getEnumerationValue(p))];
            default: break;
        };
    }
}

 

At the moment, I see the problem in the different shape of objects, which makes it difficult to position them with pixel accuracy.

Likes

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
Adobe Community Professional ,
Jun 18, 2022 Jun 18, 2022

Copy link to clipboard

Copied

LATEST

@xcptn - are you out there?

Likes

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