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

Option for placing layer as link as default

Community Beginner ,
Jun 28, 2024 Jun 28, 2024

Copy link to clipboard

Copied

I would love to have an option in the settings, where I can decide, if I want an image as a layer to be linked, not embeded by default (similar to how in InDesign works). It would reduce the file sizes a lot, and I do work with files, that are just too big (eg. 22gb .psb files), and makeing them linkable is kinda bad right now.

Idea No status
TOPICS
Actions and scripting , macOS , Windows

Views

142

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
3 Comments
Community Expert ,
Jun 28, 2024 Jun 28, 2024

Copy link to clipboard

Copied

@glamorous_problem5EB7 

 

Where do the SO layers originate from?  Are they placed? Photoshop can already place linked or embedded using the file menu (but not from drag-n-drop from outside Photoshop).

 

Are the SO layers converted from standard layer content?

 

Can you please explain step-by-step and or add any screenshots that may help to illustrate how you are getting an embedded SO layer and not linked?

 

I did make a script to automate the creation of a linked SO from an embedded SO in another topic. Perhaps it will help you:

 

 
EDIT: Apologies, that script was to create a new copy/duplicate linked SO from a linked SO (automating breaking the link to the original file and linking to a new saved file), not to create a linked SO from an embedded SO.

Votes

Translate

Translate

Report

Report
Community Expert ,
Jun 29, 2024 Jun 29, 2024

Copy link to clipboard

Copied

There is the native command in the Layers > Smart Object menu.

 

The following script will create a linked SO from an embedded SO with some enhancements over the native command.

 

Notes:

  • Select a single embedded SO layer
  • The new PSB file will be saved to the same location as the parent document
  • If the parent document is unsaved, you will be prompted for a save location
  • If there is already a PSB file with the same file name, the script will be cancelled without overwriting
  • You can then go back and rename the layer in the parent document and run the script again
  • The saved PSB file name will be cleaned of any layer name characters that are illegal for file names

 

/* 
New Linked Smart Object from Embedded.jsx
v1.0 - 29th June 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-ideas/option-for-placing-layer-as-link-as-default/idc-p/14707763
Related topics:
https://community.adobe.com/t5/photoshop-ecosystem-ideas/save-multilayer-png-jpg-smart-objects-as-psb-and-automatically-replace/idi-p/12504206
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-quot-simple-quot-way-to-export-all-generation-variations/m-p/14442568
https://community.adobe.com/t5/photoshop-ecosystem-discussions/why-is-new-smart-object-via-copy-greyed-out-for-linked-smart-objects/td-p/14371680
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-way-to-use-quot-new-smart-object-via-copy-quot-in-bulk/td-p/14096358
https://community.adobe.com/t5/photoshop-ecosystem-discussions/converting-to-linked-smart-object/td-p/13357539
*/

#target photoshop

if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
    
    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'));

    if (soMoreDesc.hasKey(stringIDToTypeID('generativeDocInfo')) === true) {
        alert("Generative Fill Smart Object Layer, do nothing!");
    } else if (so.getBoolean(stringIDToTypeID("linked")) === true) {
        alert("Linked Smart Object Layer, do nothing!");
    } else {
        // Single history state undo, calling the main function
        activeDocument.suspendHistory("New Linked Smart Object from Embedded.jsx", "main()");
    }

} else {
    alert("The layer isn't a Smart Object, do nothing!");
}


function main() {

    // Save path
    try {
        app.activeDocument.path;
        var docPath = app.activeDocument.path;
    } catch (e) {
        var docPath = Folder.selectDialog("Unsaved base file, select the save location:");
    }

    // Set the name of the SO using the parent doc layer name for renaming flexibility, rather than using the embedded SO doc name
    // Clean the layer name to remove any illegal file name
    var theSOname = app.activeDocument.activeLayer.name.replace(/[<>:"\/\\|?*\x00-\x1F]/g, '');

    // Set the file object
    var thePSB = new File(docPath + "/" + theSOname + ".psb");

    // Edit the SO, no error checking, assumes that the file can be opened by Photoshop, i.e. not vector
    app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));

    // Pass - Only save and link if there is no matching file object at the target path
    if (!thePSB.exists) {

        // Save the 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"), thePSB);
        descriptor.putBoolean(s2t("lowerCase"), true);
        executeAction(s2t("save"), descriptor, DialogModes.NO);
        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

        // Relink the embedded SO to the newly saved PSB
        var theAD = new ActionDescriptor();
        theAD.putPath(stringIDToTypeID("null"), thePSB);
        executeAction(stringIDToTypeID("placedLayerRelinkToFile"), theAD, DialogModes.NO);

        // End of script notification
        alert('The embedded smart object has been saved as a linked smart object!');
    
    // Fail - a matching file object was found
    } else {
        // You can always go back and rename the layer to manually avoid overwriting duplicates
        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        alert('File "' + thePSB.fsName + '" exists, script cancelled!');
    }

}

 

Edit: another scripted option would be to link a different file on disk replacing the embedded.

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

Votes

Translate

Translate

Report

Report
Community Beginner ,
Sep 25, 2024 Sep 25, 2024

Copy link to clipboard

Copied

LATEST

Hi Stephen, I've just put together a script to convert all embedded SO in the active Photoshop doc to a specific folder. Each file has the layer name and is saved in the same format as the original (not just PSB). Same layer name equals to same linked file, so no redundancy.

 

#target photoshop

// Prompt the user to select the folder to save linked files
var linkFolder = Folder.selectDialog("Select the folder to save linked files:");
if (linkFolder == null) {
alert("No folder selected. Operation canceled.");
exit();
}

// Get the active document
var doc = app.activeDocument;

// Create an object to keep track of already saved files
var savedFiles = {};

// Main function to convert embedded Smart Objects to linked ones
function convertAllSmartObjectsToLinked() {
var layers = getAllLayers(doc);

for (var i = 0; i < layers.length; i++) {
var layer = layers[i];

// Check if the layer is a Smart Object
if (layer.kind == LayerKind.SMARTOBJECT) {
var layerName = layer.name;

// If a file with the same name already exists, link it
if (savedFiles[layerName]) {
relinkToExisting(layer, savedFiles[layerName]);
} else {
// Otherwise, convert the embedded object to linked and save it
var linkedFile = convertToLinked(layer, layerName);
if (linkedFile) {
savedFiles[layerName] = linkedFile;
}
}
}
}
}

// Function to get all layers in the document (including nested ones)
function getAllLayers(document) {
var layers = [];
for (var i = 0; i < document.layers.length; i++) {
collectAllLayers(document.layers[i], layers);
}
return layers;
}

// Recursive function to collect layers from artboards or groups
function collectAllLayers(layer, collectedLayers) {
if (layer.typename === "ArtLayer" || layer.kind == LayerKind.SMARTOBJECT) {
collectedLayers.push(layer);
} else if (layer.typename === "LayerSet") {
for (var i = 0; i < layer.layers.length; i++) {
collectAllLayers(layer.layers[i], collectedLayers);
}
}
}

// Function to convert an embedded Smart Object to a linked one
function convertToLinked(layer, layerName) {
try {
app.activeDocument.activeLayer = layer;

// Retrieve the original format of the embedded object
var originalFormat = getSmartObjectFileExtension(layer);

if (!originalFormat) {
alert("Unable to determine the format of the Smart Object " + layerName);
return null;
}

// Create the path for the linked file with the correct format
var filePath = new File(linkFolder + "/" + layerName + "." + originalFormat);

// Use the native Photoshop command to convert the object to linked
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putPath(charIDToTypeID("Usng"), filePath);
executeAction(stringIDToTypeID("placedLayerConvertToLinked"), desc, DialogModes.NO);

return filePath;
} catch (e) {
alert("Error converting " + layerName + " to linked object: " + e.message);
return null;
}
}

// Function to relink a Smart Object to an already existing file
function relinkToExisting(layer, linkedFile) {
try {
app.activeDocument.activeLayer = layer;

var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putPath(charIDToTypeID("Usng"), linkedFile);
executeAction(stringIDToTypeID("placedLayerRelinkToFile"), desc, DialogModes.NO);
} catch (e) {
alert("Error relinking " + layer.name + ": " + e.message);
}
}

// Function to get the original Smart Object file extension
function getSmartObjectFileExtension(layer) {
try {
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));
ref.putIdentifier(stringIDToTypeID("layer"), layer.id);
var desc = executeActionGet(ref);
var fileRef = desc.getObjectValue(stringIDToTypeID("smartObject")).getString(stringIDToTypeID("fileReference"));

var extIndex = fileRef.lastIndexOf(".");
if (extIndex > -1) {
return fileRef.substr(extIndex + 1).toLowerCase();
}
return null;
} catch (e) {
alert("Error retrieving the file extension for " + layer.name + ": " + e.message);
return null;
}
}

// Execute the conversion
convertAllSmartObjectsToLinked();

alert("Conversion completed!");

Votes

Translate

Translate

Report

Report