• Global community
    • Language:
      • Deutsch
      • English
      • EspaƱol
      • FranƧais
      • PortuguĆŖs
  • ę—„ęœ¬čŖžć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£
    Dedicated community for Japanese speakers
  • ķ•œźµ­ ģ»¤ė®¤ė‹ˆķ‹°
    Dedicated community for Korean speakers
Exit
1

Determine Smart Object Attributes - Linked - Embedded - Missing - Path

Enthusiast ,
Jan 08, 2024 Jan 08, 2024

Copy link to clipboard

Copied

I've found a few older threads on Smart Objects, but none with a direct solution in this forum for getting smart object attributes.

Some of the older threads reference a try catch around placing a layer to determine if it's embedded:

 

        executeAction( stringIDToTypeID( "placedLayerConvertToEmbedded" ), undefined, DialogModes.NO );

 

 
I did find this thread on Stack Overflow, and am wondering if there are any other direct methods of getting info from a smart object.

https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-js...

I've compiled a few separate scripts to determine the extension of the smart object, to evaluate if it's vector or raster.

Is there a more direct way to evaluate smart objects? I use script listener, but not well enough to understand how I can generate a true false value etc.
TOPICS
Actions and scripting

Views

198

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 Expert ,
Jan 08, 2024 Jan 08, 2024

Copy link to clipboard

Copied

From the same link:

 

// Check Test Get Property for Linked Smart Object.jsx

/* Based on:
https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
*/

var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));

if (so.getBoolean(stringIDToTypeID("linked"))) {
  alert("Linked");
} else {
  alert("Embedded");
}

Votes

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
Community Expert ,
Jan 08, 2024 Jan 08, 2024

Copy link to clipboard

Copied

Another one:

 

/*
https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
*/

var mySO = getSmartObjectReference();

if (mySO.found) {
  alert('Is linked: ' + mySO.linked + '\nFile Name: ' + mySO.fileRef + '\nFile Path: ' + mySO.filePath);
}

function getSmartObjectReference()
{
  try
  {
    var smartObject = {
      found: false,
      fileRef: '',
      filePath: '',
      linked: false,
    };
    var ref, so;
    ref = new ActionReference();
    ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
    smartObject.found = true;
    smartObject.linked = so.getBoolean(stringIDToTypeID("linked"));
    smartObject.fileRef = so.getString(stringIDToTypeID("fileReference"));
    if (smartObject.linked) {
      smartObject.filePath = so.getPath(stringIDToTypeID("link"));
    } else {
      smartObject.filePath = Folder.temp + '/' + smartObject.fileRef;
    }
    return smartObject;
  }
  catch (e)
  {
    alert(e);
    return smartObject;
  }
}

Votes

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 ,
Jan 08, 2024 Jan 08, 2024

Copy link to clipboard

Copied

I've been using getSmartObjectReference(), wrapped in a loop that cycles through layers.

lyrSOInfo = getSmartObjectReference();
if(lyrSOInfo.filePath == '') alert("Linked File Is Missing")
if (lyrSOInfo.linked == true && lyrSOInfo.filePath != '') {
//Embed linked file
executeAction( stringIDToTypeID( "placedLayerConvertToEmbedded" ), undefined, DialogModes.NO );
}


By default it throws an error so I commented out alert(e), and I guess I could use found rather than testing the filePath directly.

Votes

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
Community Expert ,
Jan 08, 2024 Jan 08, 2024

Copy link to clipboard

Copied

What do you actually want to achieve? 

Just a list of all linked SO, a list of the pathā€™s of the linked files, ā€¦? 

Votes

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 ,
Jan 09, 2024 Jan 09, 2024

Copy link to clipboard

Copied

I'm evaluating each smart object in a file, and looking for something similar to InDesign's LinkStatus. When searching adobe forums, the tops hits that popped up were similar to the link/script below: https://community.adobe.com/t5/photoshop-ecosystem-discussions/file-information-for-smart-objects/m-...

Quoted from link:

var idplacedLayerConvertToEmbedded = stringIDToTypeID( "placedLayerConvertToEmbedded" );
executeAction( idplacedLayerConvertToEmbedded, undefined, DialogModes.NO );
theDoc.activeHistoryState = theDoc.historyStates[theDoc.historyStates.length-2];
alert ("linked")

 
getSmartObjectReference() works, but I wanted to ask on this forum as a recent answer also doesn't seem to be captured, at least the way I'm asking.

I'm using the link status/if statements to then trigger PS to embed linked Smart Objects.

Votes

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
Community Expert ,
Jan 09, 2024 Jan 09, 2024

Copy link to clipboard

Copied

Your refer to a thread from 2014; SOā€™s AM-accessibility has been improved over time, so that does not seem useful. 

Have you seen this thread? 

https://community.adobe.com/t5/photoshop-ecosystem-ideas/is-there-an-option-that-shows-me-a-list-wit...

 

Votes

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
Community Expert ,
Jan 09, 2024 Jan 09, 2024

Copy link to clipboard

Copied

quote

I'm evaluating each smart object in a file, and looking for something similar to InDesign's LinkStatus.

What do you actually mean? Please elaborate, post a meaningful screenshot/sketch ā€¦ 

Votes

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 ,
Jan 09, 2024 Jan 09, 2024

Copy link to clipboard

Copied

Thanks for the link, I'll check it out.

Below is an excerpt of how I'm using the link status, since I've compiled from different scripts/functions it's not easy to show.

Please note, the below excerpts also utilize objectIsPsObject(SOlayer), in this script, but as it's lengthy I've omitted from this thread:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/extendscript-photoshop-edit-contents-...

 

		//Layer can be set with a loop for each active layer
		layer = app.activeDocument.activeLayer;

                /******
		objectIsPsObject(layer) default determines as a raster smart object
		*******/
                if (layer.kind == LayerKind.SMARTOBJECT && objectIsPsObject(layer) == true) {
                    layer.rasterize(RasterizeType.ENTIRELAYER)
                }
                /******
                objectIsPsObject(layer) anything remaining is assumed a vector smart object and will be embedded or rasterized if missing
	        ******/
                if (layer.kind == LayerKind.SMARTOBJECT && objectIsPsObject(layer) == false) {
                    lyrSOStat = psGetSmartObjectReference();
                    //Check if file is linked, and if it is embed it
                    //Must check that the file path is not empty or it will error out when trying to embed
                    if (lyrSOStat.linked == true && lyrSOStat.filePath != '') executeAction( stringIDToTypeID( "placedLayerConvertToEmbedded" ), undefined, DialogModes.NO); 
                    //If FilePath is missing, rasterize the layer
                    if (lyrSOStat.filePath == '') layer.rasterize(RasterizeType.ENTIRELAYER);
                }

 

Votes

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
Community Expert ,
Jan 09, 2024 Jan 09, 2024

Copy link to clipboard

Copied

Will you please tell me what you actually want to achieve

A dialog with the information, text in the clipboard, a Panel, ā€¦? 

Votes

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 ,
Jan 09, 2024 Jan 09, 2024

Copy link to clipboard

Copied

Sorry for any confusion, I'm just asking if there is a more direct way to get link statuses for smart objects within a script and then run a function based on that.

In Indesign, there are 5 statuses LinkStatus.LINK_MISSING, LinkStatus.LINK_OUT_OF_DATE, LinkStatus.LINK_INACCESSIBLE, LinkStatus.LINK_EMBEDDED, and LinkStatus.NORMAL. I was asking to see if there is a photoshop equivalent.

I have yet to review the link you sent, though I did see the stack overflow link in there as well. Thanks again.

Votes

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
Community Expert ,
Jan 10, 2024 Jan 10, 2024

Copy link to clipboard

Copied

LATEST

Screenshot 2024-01-10 at 13.51.21.png

// 2024, use it at your own risk;
if (app.documents.length > 0) {
var theThings = collectSmartObjectsWithLayerComps();
var theString = "smart objects are";
for (var m = 0; m < theThings.length; m++) {
    var thisOne = theThings[m];
    theString = theString + "\n\n" + thisOne[0] + "\nis linked: " + thisOne[1]; 
    if (thisOne[1] == true) {theString = theString + "\nlink missing: " + thisOne[2] + "\nlink changed; " + thisOne[3]}
};
alert (theString);
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjectsWithLayerComps () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
    var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
    var theFileRef = soDesc.getString(stringIDToTypeID('fileReference'));
    var theDocID = soDesc.getString(stringIDToTypeID('documentID'));
    var isLinked = soDesc.getBoolean(stringIDToTypeID('linked'));
    if (isLinked == true) {
    var isMissing = soDesc.getBoolean(stringIDToTypeID('linkMissing'));
    var isChanged = soDesc.getBoolean(stringIDToTypeID('linkChanged'));
    } else {
    var isMissing = undefined;
    var isChanged = undefined;
    };
    /*var x = soDesc.getList(stringIDToTypeID("compsList"));
    var theCompsList = soDesc.getObjectValue(stringIDToTypeID("compsList"));
    if (theCompsList.count > 2) {
        var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
        var theSOComps = new Array;
        for (var n = 0; n < theCompsList.count; n++) {
        var thisOne = theCompsList.getObjectValue(n);
        var compName = thisOne.getString(stringIDToTypeID("name"));
        var compID = thisOne.getInteger(stringIDToTypeID("ID"));
        var theComment = thisOne.getString(stringIDToTypeID("comment"));
        theSOComps.push([compName, compID, theComment]);
        };
        theLayers.push([theName, theID, theFileRef, theDocID])
        theLayers.push([theName, theID, theFileRef, theDocID, theSOComps])
    };*/
    theLayers.push([theName, isLinked, isMissing, isChanged, theID, theFileRef, theDocID])
}
}
}
catch (e) {};
};
return theLayers
};

Votes

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