Copy link to clipboard
Copied
Hi
It's really annoying that, when editing a dynamic object made of one single layer, you can't add more layers. You have then to flatten its contents so that it has only one layer, as it did originally, once the modifications have been made.
Is it not possible to let us add the layers we want, and to be able to save the dynamic object without this window explaining this restriction?
Thanks
PNG files don't support multiple layers (only a single floating layer or flattened Background layer).
Smart objects when created in Photoshop from regular layer content are embedded as PSB format, which does support multiple layers.
If you place or drag in a PNG, JPEG or other file format from outside Photoshop, it is either embedded or linked in the original format.
You can always rasterise* the placed embedded PNG/JPEG and then convert it to a smart object, which will create an embedded
...Copy link to clipboard
Copied
Is the original embedded smart object in a format that doesn't accept multiple layers (JPEG, PNG etc)?
Copy link to clipboard
Copied
In that case for example, it's a smart object that is a PNG. I can't save if I edit and add more layers.
I put the smart object only in this PSD file https://www.transfernow.net/dl/20250313r3H2Qga6
But what I don't understand is that if I try to reproduce it with a PNG from the scene, right-click to convert it into a smart object and edit it, then I'm able to add more layers and save....
Copy link to clipboard
Copied
PNG files don't support multiple layers (only a single floating layer or flattened Background layer).
Smart objects when created in Photoshop from regular layer content are embedded as PSB format, which does support multiple layers.
If you place or drag in a PNG, JPEG or other file format from outside Photoshop, it is either embedded or linked in the original format.
You can always rasterise* the placed embedded PNG/JPEG and then convert it to a smart object, which will create an embedded PSB (*Rasterising the smart object will convert a scaled image to the current scaled size, so isn't always a perfect solution, a scripted solution can overcome this limitation without manual steps).
Edit: For sake of completeness, to do this manually:
* Edit the smart object layer
* Save As a copy to PSB
* Close the edited smart object
* Replace the smart object with the PSB
Copy link to clipboard
Copied
The following legacy ExtendScript/JavaScript code will convert the embedded smart object to an embedded PSB, allowing layers to be seamlessly added.
/*
Create Embedded PSB from Smart Object Layer 1-2.jsx
Stephen Marsh
v1.0 - 14th March 2025: Initial release
v1.1 - 6th April 2025: Added a check to ensure that only Embedded Smart Objects are processed
v1.2 - 7th April 2025: Added a check to ensure that the Embedded Smart Object is supported by Photoshop for editing
https://community.adobe.com/t5/photoshop-ecosystem-ideas/editing-and-saving-a-dynamic-object-with-more-layers/idc-p/15210208
INFO: Run this script on an Embedded Smart Object to replace it as a PSB file (example, automatically convert an embedded JPEG to PSB so that it can accept layers).
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-ideas/save-multilayer-png-jpg-smart-objects-as-psb-and-automatically-replace/idi-p/12504206
*/
#target photoshop;
try {
// Check if a document is open
if (app.documents.length === 0) {
throw new Error("Error: A document must be open!");
}
// Check if the active layer is a Smart Object
if (app.activeDocument.activeLayer.kind != LayerKind.SMARTOBJECT) {
throw new Error("Error: The layer isn't a Smart Object!");
}
// Additional AM code checks for the Smart Object
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDesc = executeActionGet(ref);
ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));
// Check if the Smart Object is a Generative AI layer
if (soMoreDesc.hasKey(stringIDToTypeID('generativeDocInfo')) === true) {
throw new Error("Error: A Generative Fill Smart Object isn't a supported layer type!");
}
// Check if the Smart Object is linked
if (so.getBoolean(stringIDToTypeID("linked")) === true) {
throw new Error("Error: A Linked Smart Object isn't a supported layer type!");
}
// Check if the embedded Smart Object is a supported for direct editing in Photoshop, and not a raw camera file or container file (e.g. PDF, EPS, AI)
var theSOlayer = app.activeDocument.activeLayer;
ref.putIdentifier(charIDToTypeID("Lyr "), theSOlayer.id);
var desc = executeActionGet(ref);
var smObj = desc.getObjectValue(stringIDToTypeID("smartObject"));
var fileRef = smObj.getString(stringIDToTypeID("fileReference"));
var fileExtension = fileRef.match(/\.([a-zA-Z0-9]+)$/i)[1];
var validExtensions = /^(psd|psb|jpeg|jpg|tiff|tif|tga|png|webp|gif)$/i;
if (validExtensions.test(fileExtension)) {
// Edit the original embedded SO
app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
// Create a temp folder with a name based on datetime
function pad(number, length) {
var str = '' + number;
while (str.length < length) {
str = '0' + str;
}
return str;
}
function getFormattedDateTime() {
var now = new Date();
var day = pad(now.getDate(), 2);
var month = pad(now.getMonth() + 1, 2); // Months are zero-based
var year = now.getFullYear();
var hours = pad(now.getHours(), 2);
var minutes = pad(now.getMinutes(), 2);
var seconds = pad(now.getSeconds(), 2);
var milliseconds = pad(now.getMilliseconds(), 3);
return day + month + year + hours + minutes + seconds + milliseconds;
}
var timestamp = getFormattedDateTime();
var theTempDir = new Folder("~/Desktop/_theTempDir_" + timestamp);
if (theTempDir.exists) {
throw new Error("Error: Script cancelled as the temporary desktop folder already exists!");
}
theTempDir.create();
// Save the open edited embedded image to a temp PSB file
var thePSB = theTempDir + "/" + app.activeDocument.name.replace(/\.[^\.]+$/, '') + ".psb";
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor2.putBoolean(s2t("maximizeCompatibility"), true);
descriptor.putObject(s2t("as"), s2t("largeDocumentFormat"), descriptor2);
descriptor.putPath(s2t("in"), new File(thePSB));
descriptor.putBoolean(s2t("lowerCase"), true);
descriptor.putEnumerated(s2t("saveStage"), s2t("saveStageType"), s2t("saveSucceeded"));
executeAction(s2t("save"), descriptor, DialogModes.NO);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Replace the original embedded file with the temp PSB file
descriptor = new ActionDescriptor();
descriptor.putPath(s2t("null"), new File(thePSB));
executeAction(s2t("placedLayerReplaceContents"), descriptor, DialogModes.NO);
// Remove the temp PSB before the temp folder can be removed
thePSB = new File(thePSB);
thePSB.remove();
// Remove the empty temp folder
theTempDir.remove();
// End of script notification
// alert("The embedded Smart Object has been replaced with a PSB file!");
app.beep();
} else {
throw new Error("Error: The embedded Smart Object isn't a supported file type for automated PSB replacement!");
}
} catch (e) {
alert(e.message);
}
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
Awesome, thanks for clarifying that point 🙂
Cheers
Michel