Skip to main content
New Participant
April 25, 2024
Question

Resizing object to guidelines

  • April 25, 2024
  • 5 replies
  • 1349 views

Hi, I would like to know if there is a photoshop script that is capable of detecing the product in the photo and resize it so that it rests on the bottom baseline and its sides touching the 2 vertical guidelines. i have attached an example of what i would like to achieve.

 

i am on mac os

 

thank u so much in advance!!!! 🙂

This topic has been closed for replies.

5 replies

willcampbell7
Brainiac
May 9, 2024

See if this script helps. You have to use Select Subject first, or get the selection some other way, then run the script which does the scaling and positioning to the guides. Edit the code as needed if it doesn't quite do what you need.

https://www.marspremedia.com/software/photoshop/fit-to-guides

 

William Campbell
Stephen Marsh
Community Expert
May 2, 2024

@Annabelle34201152okys – how did the 2 script solutions that I created for you work out?

New Participant
May 3, 2024

hi stephen! sorry for the late reply! i have been overloaded at work lol.

i'll check it out today! thank you for taking time to write the script!

Stephen Marsh
Community Expert
April 27, 2024

@Annabelle34201152okys 

 

This 1.1 version attempts to fully automate the sizing and positioning without any interactivity. Adjustments can be made from your feedback. The move tool is selected at the end of the script so that you can use the arrow cursor keys or shift + arrow cursor keys to nudge the product into position if the calculated position is slightly off.

 

/*
Resize Product and Position on Template.jsx
v1.1 - 27th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/resizing-object-to-guidelines/td-p/14578063
*/

#target photoshop

// Get the original ruler units and set the rulers to px
var origRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Set the template doc name
var templateDocName = app.activeDocument.name;

// Open the product image
open(File.openDialog("Select the product file to add:"));

// Select Subject
executeAction(stringIDToTypeID('autoCutout'), new ActionDescriptor(), DialogModes.NO);

// Get the selection bounds
var selectionBounds = app.activeDocument.selection.bounds;
var selectionLeft = selectionBounds[0].value;
var selectionTop = selectionBounds[1].value;
var selectionRight = selectionBounds[2].value;
var selectionBottom = selectionBounds[3].value;
var selectionWidth = selectionBounds[2].value - selectionBounds[0].value;
var selectionHeight = selectionBounds[3].value - selectionBounds[1].value;
var selectionXCenter = (selectionLeft) + (selectionWidth / 2);
var selectionYCenter = (selectionTop) + (selectionHeight / 2);

// Calculate the % reduction
var resizePercentage = Math.round(1652 / selectionWidth * 100);

// Deselect
app.activeDocument.selection.deselect();

// Set the product doc name
var productDocName = app.activeDocument.name.replace(/\.[^\.]+$/, '');

// Add the product to the template
function s2t(s) {
    return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putName( s2t( "document" ), templateDocName );
descriptor.putReference( s2t( "to" ), reference2 );
descriptor.putString( s2t( "name" ), productDocName );
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);

// Close the product doc
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

// Centre the product on the template
var docLay = app.activeDocument.activeLayer;
docLay.translate(app.activeDocument.width / 2 - (docLay.bounds[0] + docLay.bounds[2]) / 2, 
    app.activeDocument.height / 2 - (docLay.bounds[1] + docLay.bounds[3]) / 2);

// Resize
function s2t(s) {
    return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSAverage" ));
descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), 0 );
descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), 0 );
descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
descriptor.putUnitDouble( s2t( "width" ), s2t( "percentUnit" ), resizePercentage );
descriptor.putUnitDouble( s2t( "height" ), s2t( "percentUnit" ), resizePercentage );
descriptor.putEnumerated( s2t( "interfaceIconFrameDimmed" ), s2t( "interpolationType" ), s2t( "bicubicSmoother" ));
executeAction(s2t("transform"), descriptor, DialogModes.NO);

// Select Subject    
executeAction(stringIDToTypeID('autoCutout'), new ActionDescriptor(), DialogModes.NO);

// Calculate the offset from the bottom guide position
var offsetValue = app.activeDocument.selection.bounds[3].value - 2100;

// Deselect
app.activeDocument.selection.deselect();

// Offset the layer
var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putInteger( s2t( "horizontal" ), 0 );
descriptor.putInteger( s2t( "vertical" ), -offsetValue );
descriptor.putEnumerated( s2t( "fill" ), s2t( "fillMode" ), s2t( "background" ));
executeAction( s2t( "offset" ), descriptor, DialogModes.NO );
// Move the layer
//app.activeDocument.activeLayer.translate(0, -offsetValue);

// Remove any "big data" extending beyond the canvas
app.activeDocument.selection.selectAll();
new ActionDescriptor().putBoolean(charIDToTypeID('Dlt '), true);
executeAction(charIDToTypeID('Crop'), new ActionDescriptor(), DialogModes.NO);
app.activeDocument.selection.deselect();

// Remove document ancestors metadata from the template
// https://prepression.blogspot.com/2017/06/metadata-bloat-photoshopdocumentancestors.html
// https://forums.adobe.com/message/8456985#8456985
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();

// Select the move tool
(r = new ActionReference()).putClass(stringIDToTypeID('moveTool'));
(d = new ActionDescriptor()).putReference(stringIDToTypeID('target'), r);
executeAction(stringIDToTypeID('select'), d, DialogModes.NO);

// Return the original ruler units
app.preferences.rulerUnits = origRulerUnits;

 

 

Stephen Marsh
Community Expert
April 27, 2024

@Annabelle34201152okys 

 

Have the template doc open/active, then run the following script. You will be prompted to select the product image to add to the template. The product image will be placed and approximately resized to the 1652px width defined by the guides via an interactive transformation step for you to refine the final size and position relative to the 3 visible guides. When you are happy with the size and position, commit the transform (press the tick button).

 

It is possible to place the variable position of the product to the baseline guide, however, this takes more work to script. A generic vertical adjustment is made, however, this will likely vary from product to product. As the calculated resize width may not be 100% correct anyway, it just seems more practical to manually adjust both the size and position via the interactive transform step.

 

Let me know your thoughts.

 

/*
Resize Product and Position on Template.jsx
v1.0 - 27th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/resizing-object-to-guidelines/td-p/14578063
*/

#target photoshop

// Get the original ruler units and set the rulers to px
var origRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Set the template doc name
var templateDocName = app.activeDocument.name;

// Open the product image
open(File.openDialog("Select the product file to add:"));

// Select Subject    
executeAction(stringIDToTypeID('autoCutout'), new ActionDescriptor(), DialogModes.NO);

// Get the selection bounds
var selectionBounds = app.activeDocument.selection.bounds;
var selectionLeft = selectionBounds[0].value;
var selectionTop = selectionBounds[1].value;
var selectionRight = selectionBounds[2].value;
var selectionBottom = selectionBounds[3].value;
var selectionWidth = selectionBounds[2].value - selectionBounds[0].value;
var selectionHeight = selectionBounds[3].value - selectionBounds[1].value;
var selectionXCenter = (selectionLeft) + (selectionWidth / 2);
var selectionYCenter = (selectionTop) + (selectionHeight / 2);

// Calculate the % reduction
var resizePercentage = Math.round(1652 / selectionWidth * 100);

// Deselect
app.activeDocument.selection.deselect();

// Set the product doc name
var productDocName = app.activeDocument.name.replace(/\.[^\.]+$/, '');

// Add the product to the template
function s2t(s) {
    return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putName( s2t( "document" ), templateDocName );
descriptor.putReference( s2t( "to" ), reference2 );
descriptor.putString( s2t( "name" ), productDocName );
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);

// Close the product doc
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

// Centre the product on the template
var docLay = app.activeDocument.activeLayer;
docLay.translate(app.activeDocument.width / 2 - (docLay.bounds[0] + docLay.bounds[2]) / 2, 
    app.activeDocument.height / 2 - (docLay.bounds[1] + docLay.bounds[3]) / 2);

// Instructions
alert("Adjust the transform size and position to the guides and commit...");

// Interactive transform
function s2t(s) {
    return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSAverage" ));
descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), 0.000000 );
descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), -430 );
descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
descriptor.putUnitDouble( s2t( "width" ), s2t( "percentUnit" ), resizePercentage );
descriptor.putUnitDouble( s2t( "height" ), s2t( "percentUnit" ), resizePercentage );
descriptor.putEnumerated( s2t( "interfaceIconFrameDimmed" ), s2t( "interpolationType" ), s2t( "bicubicSmoother" ));
executeAction( s2t( "transform" ), descriptor, DialogModes.ALL );

// Remove any "big data" extending beyond the canvas
app.activeDocument.selection.selectAll();
new ActionDescriptor().putBoolean(charIDToTypeID('Dlt '), true);
executeAction(charIDToTypeID('Crop'), new ActionDescriptor(), DialogModes.NO);
app.activeDocument.selection.deselect();

// Remove document ancestors metadata from the template
// https://prepression.blogspot.com/2017/06/metadata-bloat-photoshopdocumentancestors.html
// https://forums.adobe.com/message/8456985#8456985
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();

// Return the original ruler units
app.preferences.rulerUnits = origRulerUnits;

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

Stephen Marsh
Community Expert
April 25, 2024

I would think that one would have to be specifically written.

 

If there were 4 guides marking the bounding area to resize to:

 

Dupe layer

Isolate product via select subject

Copy to new layer

Transform layer bounds to guides

Delete the layer

Transform again on the original layer (to get the scale, but not position)

 

But that is just a rough idea, it may or may not be that "simple"!

 

New Participant
April 26, 2024

hi stephen!

thank you for the speedy reply! 4 guides, you mean like 1 more guideline at the top? but every shoe has varying heights so i'm not sure how the 4th guideline would look like.

do you have any advise? or would it not be possible to achieve?

thank you again!

Stephen Marsh
Community Expert
April 26, 2024

Yes, a guide at the top.

 

How are the guides being added? I presume manually for each product...

 

I don't believe that I could fully automate this, perhaps only partially automate the task. Others may be able to offer more.

 

More info on your step-by-step workflow and original images would be required.