Copy link to clipboard
Copied
When placing a 600 PPI resolution document into a 300 PPI document, the Smart Object layer is initially sized at 50%. Both Place Embedded and Place Linked behave this way, it is by design.
Users sometimes want to place images at their original pixel size, regardless of mismatching PPI values.
A recent post on the forum has reminded me that I created the following scripts over a year ago, however, I don't believe that I ever posted them.
The scripts have not been exhaustively tested, so please let me know if there are any issues. Code below!
Copy link to clipboard
Copied
Place Embedded Retaining Pixel Size:
/*
Place Embedded Retaining Pixel Size.jsx
v1.0 - 13th June 2022, Stephen Marsh
v1.1 - 5th April 2024: Added a conditional version check
v1.2 - 5th April 2024: Added a conditional layer bounds vs. canvas check
*/
#target photoshop
function main() {
// Ensure that version 2021 or later is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
// Fail
if (versionCheck <= 21) {
alert("This script is for Photoshop 2021 or later...");
// Pass
} else {
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Conditionally activate "Skip Transform When Placing" General Preference
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var applicationDesc = executeActionGet(ref);
var skipTransformPref = applicationDesc.getObjectValue(stringIDToTypeID("generalPreferences")).getBoolean(stringIDToTypeID("skipTransformSOFromLibrary"));
if (skipTransformPref === false) {
skipTransform(true);
}
// Conditionally deactivate "Resize During Place" General Preference
var aref = new ActionReference();
aref.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var appDesc = executeActionGet(aref);
var resizePlacePref = appDesc.getObjectValue(stringIDToTypeID("generalPreferences")).getBoolean(stringIDToTypeID("resizePastePlace"));
if (resizePlacePref === true) {
resizeDuringPlace(false);
}
// Call the place embedded dialog
placeEmbedded();
// Set the active layer
var theSO = app.activeDocument.activeLayer;
// Reset the SO transform
var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
// Get the layer bounds
var layWidth = app.activeDocument.activeLayer.bounds[2].value - app.activeDocument.activeLayer.bounds[0].value;
var layHeight = app.activeDocument.activeLayer.bounds[3].value - app.activeDocument.activeLayer.bounds[1].value;
// Optionally handle oversized content
if (layWidth > app.activeDocument.width.value || layHeight > app.activeDocument.height.value) {
if (confirm("Convert Background to layer & reveal all content?", true)) {
// Select the Background layer if it exists (silently fails if there is no such layer)
try {
app.activeDocument.activeLayer = app.activeDocument.backgroundLayer;
} catch (error) { }
// Convert the Background layer to a normal layer
if (app.activeDocument.activeLayer.isBackgroundLayer) {
app.activeDocument.activeLayer.isBackgroundLayer = false;
app.activeDocument.activeLayer.name = "Background";
}
app.activeDocument.revealAll();
app.activeDocument.activeLayer = theSO;
}
}
// Reset General Preferences back to their original state
skipTransform(skipTransformPref);
resizeDuringPlace(resizePlacePref);
app.preferences.rulerUnits = savedRuler;
}
}
app.activeDocument.suspendHistory("Place Embedded Retaining Pixel Size.jsx", "main()");
// Functions
function placeEmbedded() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("menuItemClass"), s2t("menuItemType"), s2t("placeEnum"));
descriptor.putReference(s2t("null"), reference);
executeAction(s2t("select"), descriptor, DialogModes.ALL);
}
/*
Preference functions based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-change-photoshop-preferences-by-script-resize-image-during-place/m-p/12544913
https://community.adobe.com/t5/photoshop-ecosystem-discussions/can-you-also-read-a-photoshop-preference-like-quot-resize-image-during-place-quot/m-p/12752645
*/
function skipTransform(setBoolean) {
sTT = stringIDToTypeID;
(ref = new ActionReference()).putProperty(
sTT("property"),
(gP = sTT("generalPreferences"))
);
ref.putClass(sTT("application"));
(dsc1 = new ActionDescriptor()).putReference(sTT("null"), ref);
(dsc2 = new ActionDescriptor()).putBoolean(sTT("skipTransformSOFromLibrary"), setBoolean);
dsc1.putObject(sTT("to"), gP, dsc2), executeAction(sTT("set"), dsc1);
}
function resizeDuringPlace(setBoolean) {
sIDtID = stringIDToTypeID;
(aref = new ActionReference()).putProperty(
sIDtID("property"),
(genPref = sIDtID("generalPreferences"))
);
aref.putClass(sIDtID("application"));
(adsc1 = new ActionDescriptor()).putReference(sIDtID("null"), aref);
(adsc2 = new ActionDescriptor()).putBoolean(sIDtID("resizePastePlace"), setBoolean);
adsc1.putObject(sIDtID("to"), genPref, adsc2), executeAction(sIDtID("set"), adsc1);
}
Place Linked Retaining Pixel Size:
/*
Place Linked Retaining Pixel Size.jsx
v1.0 - 13th June 2022, Stephen Marsh
v1.1 - 5th April 2024: Added a version check
v1.2 - 5th April 2024: Added a conditional layer bounds vs. canvas check
*/
#target photoshop
function main() {
// Ensure that version 2021 or later is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
// Fail
if (versionCheck <= 21) {
alert("This script is for Photoshop 2021 or later...");
// Pass
} else {
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Conditionally activate "Skip Transform When Placing" General Preference
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var applicationDesc = executeActionGet(ref);
var skipTransformPref = applicationDesc.getObjectValue(stringIDToTypeID("generalPreferences")).getBoolean(stringIDToTypeID("skipTransformSOFromLibrary"));
if (skipTransformPref === false) {
skipTransform(true);
}
// Conditionally deactivate "Resize During Place" General Preference
var aref = new ActionReference();
aref.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var appDesc = executeActionGet(aref);
var resizePlacePref = appDesc.getObjectValue(stringIDToTypeID("generalPreferences")).getBoolean(stringIDToTypeID("resizePastePlace"));
if (resizePlacePref === true) {
resizeDuringPlace(false);
}
// Call the place linked dialog
placeLinked();
// Set the active layer
var theSO = app.activeDocument.activeLayer;
// Reset the SO transform
var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
// Get the layer bounds
var layWidth = app.activeDocument.activeLayer.bounds[2].value - app.activeDocument.activeLayer.bounds[0].value;
var layHeight = app.activeDocument.activeLayer.bounds[3].value - app.activeDocument.activeLayer.bounds[1].value;
// Optionally handle oversized content
if (layWidth > app.activeDocument.width.value || layHeight > app.activeDocument.height.value) {
if (confirm("Convert Background to layer & reveal all content?", true)) {
// Select the Background layer if it exists (silently fails if there is no such layer)
try {
app.activeDocument.activeLayer = app.activeDocument.backgroundLayer;
} catch (error) { }
// Convert the Background layer to a normal layer
if (app.activeDocument.activeLayer.isBackgroundLayer) {
app.activeDocument.activeLayer.isBackgroundLayer = false;
app.activeDocument.activeLayer.name = "Background";
}
app.activeDocument.revealAll();
app.activeDocument.activeLayer = theSO;
}
}
// Reset General Preferences back to their original state
skipTransform(skipTransformPref);
resizeDuringPlace(resizePlacePref);
app.preferences.rulerUnits = savedRuler;
}
}
app.activeDocument.suspendHistory("Place Linked Retaining Pixel Size.jsx", "main()");
// Functions
function placeLinked() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
descriptor.putBoolean(s2t("linked"), true);
executeAction(s2t("placeEvent"), descriptor, DialogModes.ALL);
}
/*
Preference functions based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-change-photoshop-preferences-by-script-resize-image-during-place/m-p/12544913
https://community.adobe.com/t5/photoshop-ecosystem-discussions/can-you-also-read-a-photoshop-preference-like-quot-resize-image-during-place-quot/m-p/12752645
*/
function skipTransform(setBoolean) {
sTT = stringIDToTypeID;
(ref = new ActionReference()).putProperty(
sTT("property"),
(gP = sTT("generalPreferences"))
);
ref.putClass(sTT("application"));
(dsc1 = new ActionDescriptor()).putReference(sTT("null"), ref);
(dsc2 = new ActionDescriptor()).putBoolean(sTT("skipTransformSOFromLibrary"), setBoolean);
dsc1.putObject(sTT("to"), gP, dsc2), executeAction(sTT("set"), dsc1);
}
function resizeDuringPlace(setBoolean) {
sIDtID = stringIDToTypeID;
(aref = new ActionReference()).putProperty(
sIDtID("property"),
(genPref = sIDtID("generalPreferences"))
);
aref.putClass(sIDtID("application"));
(adsc1 = new ActionDescriptor()).putReference(sIDtID("null"), aref);
(adsc2 = new ActionDescriptor()).putBoolean(sIDtID("resizePastePlace"), setBoolean);
adsc1.putObject(sIDtID("to"), genPref, adsc2), executeAction(sIDtID("set"), adsc1);
}
Info on downloading and installing/running scripts:
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html?m=1
Copy link to clipboard
Copied
Unfortunately, this no longer works. It throws an error.
Copy link to clipboard
Copied
@NicNamSam – I can see that you are on Windows, but what version/build of Photoshop?
I have tested in v2024 and 2021 on Mac without that 8800 error.
EDIT:
I have just tested in version 2020 on Windows and I do receive the 8800 error, I don't believe that this is a platform dependent issue, just a Photoshop version issue. Version 2020 didn't have the option to reset smart object transformations. I may have a v2020 specific workaround...
Copy link to clipboard
Copied
Here is a workaround for v2020 only, for the place embedded. I don't have a quick easy fix for the place linked at this time:
/*
Place Embedded Retaining Pixel Size v2020.jsx
v1.0 - 5th April 2024, Stephen Marsh
*/
#target photoshop
function main() {
// Ensure that version 2020 is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
// Fail
if (versionCheck != 21) {
alert("This script is only for Photoshop 2020!");
// Pass
} else {
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Conditionally activate "Skip Transform When Placing" General Preference
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var applicationDesc = executeActionGet(ref);
var skipTransformPref = applicationDesc.getObjectValue(stringIDToTypeID("generalPreferences")).getBoolean(stringIDToTypeID("skipTransformSOFromLibrary"));
if (skipTransformPref === false) {
skipTransform(true);
}
// Conditionally deactivate "Resize During Place" General Preference
var aref = new ActionReference();
aref.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var appDesc = executeActionGet(aref);
var resizePlacePref = appDesc.getObjectValue(stringIDToTypeID("generalPreferences")).getBoolean(stringIDToTypeID("resizePastePlace"));
if (resizePlacePref === true) {
resizeDuringPlace(false);
}
// Call the place embedded dialog
placeEmbedded();
// Reset the SO transform via convert to layers for v2020 (as "placedLayerResetTransforms" doesn't exist)
var idplacedLayerConvertToLayers = stringIDToTypeID("placedLayerConvertToLayers");
executeAction(idplacedLayerConvertToLayers, undefined, DialogModes.NO);
// Re-embed the SO
var idnewPlacedLayer = stringIDToTypeID("newPlacedLayer");
executeAction(idnewPlacedLayer, undefined, DialogModes.NO);
// Set the active layer
var theSO = activeDocument.activeLayer;
// Get the layer bounds
var layWidth = activeDocument.activeLayer.bounds[2].value - app.activeDocument.activeLayer.bounds[0].value;
var layHeight = activeDocument.activeLayer.bounds[3].value - app.activeDocument.activeLayer.bounds[1].value;
// Optionally handle oversized content
if (layWidth > activeDocument.width.value || layHeight > activeDocument.height.value) {
if (confirm("Convert Background to layer & reveal all content?", true)) {
// Select the Background layer if it exists (silently fails if there is no such layer)
try {
app.activeDocument.activeLayer = app.activeDocument.backgroundLayer;
} catch (error) { }
// Convert the Background layer to a normal layer
if (activeDocument.activeLayer.isBackgroundLayer) {
activeDocument.activeLayer.isBackgroundLayer = false;
activeDocument.activeLayer.name = "Background";
}
activeDocument.revealAll();
activeDocument.activeLayer = theSO;
}
}
// Reset General Preferences back to their original state
skipTransform(skipTransformPref);
resizeDuringPlace(resizePlacePref);
app.preferences.rulerUnits = savedRuler;
}
}
app.activeDocument.suspendHistory("Place Embedded Retaining Pixel Size.jsx", "main()");
// Functions
function placeEmbedded() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("menuItemClass"), s2t("menuItemType"), s2t("placeEnum"));
descriptor.putReference(s2t("null"), reference);
executeAction(s2t("select"), descriptor, DialogModes.ALL);
}
/*
Preference functions based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-change-photoshop-preferences-by-script-resize-image-during-place/m-p/12544913
https://community.adobe.com/t5/photoshop-ecosystem-discussions/can-you-also-read-a-photoshop-preference-like-quot-resize-image-during-place-quot/m-p/12752645
*/
function skipTransform(setBoolean) {
sTT = stringIDToTypeID;
(ref = new ActionReference()).putProperty(
sTT("property"),
(gP = sTT("generalPreferences"))
);
ref.putClass(sTT("application"));
(dsc1 = new ActionDescriptor()).putReference(sTT("null"), ref);
(dsc2 = new ActionDescriptor()).putBoolean(sTT("skipTransformSOFromLibrary"), setBoolean);
dsc1.putObject(sTT("to"), gP, dsc2), executeAction(sTT("set"), dsc1);
}
function resizeDuringPlace(setBoolean) {
sIDtID = stringIDToTypeID;
(aref = new ActionReference()).putProperty(
sIDtID("property"),
(genPref = sIDtID("generalPreferences"))
);
aref.putClass(sIDtID("application"));
(adsc1 = new ActionDescriptor()).putReference(sIDtID("null"), aref);
(adsc2 = new ActionDescriptor()).putBoolean(sIDtID("resizePastePlace"), setBoolean);
adsc1.putObject(sIDtID("to"), genPref, adsc2), executeAction(sIDtID("set"), adsc1);
}
Copy link to clipboard
Copied
It's awesome that you put the work in to address this issue. However, I have photoshop 2024, version 25.6.0 and it is giving me the error that I showed. Although weirdly it now seems to be correctly inserting the image at the original size, even though it throws the error. But I haven't tested it thoroughly with other documents.
Copy link to clipboard
Copied
Thank you for the feedback.
Are you referring to the two original place embedded and place linked scripts?
Or are you referring to the new 2020 specific place embedded version?
Copy link to clipboard
Copied
The original ones throw the error I screenshotted, and the new ones throw an error saying they are made only for the 2020 version of Photoshop.
Copy link to clipboard
Copied
The original ones throw the error I screenshotted
Thanks for confirming, as I previously wrote, I can't reproduce this 8800 error in 2021 or 2024 versions. The method exists, so I don't know why it is failing.
The new ones throw an error saying they are made only for the 2020 version of Photoshop.
By @NicNamSam
That is correct and by design, I added different code specifically for v2020 and then added a check to abort the script if another version was attempting to use the script. For the 2020 script, the version check could be removed or changed to 2024 (the script can't be used in 2019 or earlier as other code parts didn't exist in those versions):
From 2020:
if (versionCheck != 21) {
To the following for 2024:
if (versionCheck != 25) {
Or all versions from 2020:
if (versionCheck >= 21) {
Copy link to clipboard
Copied
For the 8800 error in the original two scripts, you could try to modify the following from:
// Reset the SO transform
var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
To:
// Reset the SO transform
sTID = function(s) { return app.stringIDToTypeID(s); };
executeAction(sTID('placedLayerResetTransforms'), undefined, DialogModes.NO);
I doubt that it will make any difference, but it's worth a shot!
Copy link to clipboard
Copied
Yeah, unfortunately it gives the same error. And I have to correct my previous comment because it doesn't keep the same resolution as the original despite the error message (the difference was more subtle than other times, so I didn't notice it)
Copy link to clipboard
Copied
OK, forgetting the original 2 scripts for now... Please try changing the v2020 script to be accessible for 2024 by adjusting the version check as previously described.
Please let me know how this goes.
Copy link to clipboard
Copied
Nope, same issue. It's okay, though, it looks like some weird issue on my end, I can resort to opening images and dragging them in the old way.
Copy link to clipboard
Copied
it looks like some weird issue on my end...
By @NicNamSam
Perhaps, all I know is that it works for me and not for you! :]
Please try this much simpler version, it was my initial first draft before I reworked the script. It is only for embedded:
/*
Faux Place Embedded Retaining Pixel Size.jsx
v1.0 - 12th June 2022, Stephen Marsh
v1.1 - 7th April 2024, Added a conditional layer bounds vs. canvas check
*/
#target photoshop
function main() {
// Set the ruler units to px
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Set the target doc
var targetDoc = activeDocument;
// Open menu to select the file instead of place embedded
var idopen = stringIDToTypeID("open");
executeAction(idopen, undefined, DialogModes.NO);
// Set the source doc
var sourceDoc = activeDocument;
// Set the source doc name
var sourceName = sourceDoc.name.replace(/\.[^\.]+$/, '');
// Select All
sourceDoc.selection.selectAll();
// Copy
sourceDoc.activeLayer.copy();
// Set the target doc
activeDocument = targetDoc;
// Paste
targetDoc.paste();
// Close the source doc
sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
// Rename the layer
targetDoc.activeLayer.name = sourceName;
// Convert to smart object
var idnewPlacedLayer = stringIDToTypeID("newPlacedLayer");
executeAction(idnewPlacedLayer, undefined, DialogModes.NO);
// Set the SO layer
var theSO = targetDoc.activeLayer;
// Get the layer bounds
var layWidth = targetDoc.activeLayer.bounds[2].value - targetDoc.activeLayer.bounds[0].value;
var layHeight = targetDoc.activeLayer.bounds[3].value - targetDoc.activeLayer.bounds[1].value;
// Optionally handle oversized content
if (layWidth > activeDocument.width.value || layHeight > activeDocument.height.value) {
if (confirm("Convert Background to layer & reveal all content?", true)) {
// Select the Background layer if it exists (silently fails if there is no such layer)
try {
targetDoc.activeLayer = targetDoc.backgroundLayer;
} catch (error) {}
// Convert the Background layer to a normal layer
if (targetDoc.activeLayer.isBackgroundLayer) {
targetDoc.activeLayer.isBackgroundLayer = false;
targetDoc.activeLayer.name = "Background";
}
targetDoc.revealAll();
}
}
// Select the SO layer
targetDoc.activeLayer = theSO;
// Reset the ruler prefs
app.preferences.rulerUnits = savedRuler;
}
app.activeDocument.suspendHistory("Faux Place Embedded Retaining Pixel Size.jsx", "main()");
Note:
If you do reveal all, the canvas is resized from the upper-left in this script (as opposed to the middle-centre in the previous scripts).
Copy link to clipboard
Copied
Yes, this works!
Copy link to clipboard
Copied
Yes, this works!
By @NicNamSam
This was my first draft attempt, I moved away from it's simplicity to the more complicated final versions, however I'm glad that I kept the code!
Copy link to clipboard
Copied
Thank you! Is there a feature that this older script doesn't have that the new ones do?
Copy link to clipboard
Copied
Thank you! Is there a feature that this older script doesn't have that the new ones do?
By @NicNamSam
The newer scripts use the place embedded or place linked commands and then reset the placed transformations to return to the original pixel values, among other things.
This simpler script uses copy and paste to retain the original pixel values, then it creates an embedded smart object from the pasted image.
Two different routes to the same end of an embedded smart object honouring pixel size over resolution/print size.
Copy link to clipboard
Copied
I see no problem beside anoying pop-up?
Copy link to clipboard
Copied
The "annoying" confirmation is there for a very good reason. The script could be modifed without the "nag window" if the user understands why and what is happening. :]
EDIT:
I have added an extra conditional check to only prompt to convert a background layer and expand the canvas if the embedded or linked smart object layer bounds are larger than the canvas size.
Copy link to clipboard
Copied
Yet another option is automation via the Script Events Manager:
https://prepression.blogspot.com/2021/10/photoshop-script-events-manager.html
Setup a new event that listens for the placeEvent (embedded or linked) operation:
Then create an an action to reset transformations after placing a smart object (found in the Properties panel):
Alternatively, a .jsx ExtendScript version of the same command:
#target photoshop
executeAction( stringIDToTypeID( "placedLayerResetTransforms" ), undefined, DialogModes.NO );
The placed image will be automatically reset to its original pixel values directly after placing it.