Script to Embed Displacement Map Data, CC2019

Community Beginner ,
Jul 26, 2019 Jul 26, 2019

Copy link to clipboard

Copied

I'm pretty new to scripting, and taking sort of a deep dive here. (For me at least!)

I've got a script that creates uniquely-named displacement map file, then applies the map with a Displace Smart Filter. So far so good.

What I'd really like to take advantage of though is CC2019's new "Embed File Data in Smart Object" feature. This feature prevents the 'Could not update smart object files because the file was not found' error common when moving files with displace filters applied to smart objects between different computers. This error forces the user to redo the Displace filter, and browse to the correct map file. I want to avoid making my client have to do that!

I've used r-bin's Script Event Listener to try and sus this out. It appears that the generated code stores displace data in "DspD". You'll see it in the second to last line of the code I've pasted below. (It's truncated from 30110090 to 10000.)  I assume this data is some representation of the map file. I'm wondering if there's a clever way to get that data, store it, and use it in my script. I'll be batch processing many, many files and they'll each have a unique map to grab.

        var d = new ActionDescriptor();

        d.putInteger(stringIDToTypeID("horizontalScale"), 10);

        d.putInteger(stringIDToTypeID("verticalScale"), 10);

        d.putEnumerated(stringIDToTypeID("displacementMap"), stringIDToTypeID("displacementMap"), stringIDToTypeID("stretchToFit"));

        d.putEnumerated(stringIDToTypeID("undefinedArea"), stringIDToTypeID("undefinedArea"), stringIDToTypeID("repeatEdgePixels"));

        d.putPath(stringIDToTypeID("displaceFile"), new File("~/Desktop//DisplaceMap_1668.psd"));

        d.putBoolean(charIDToTypeID("EmbF"), true);

        d.putData(charIDToTypeID("DspD"), /* real data length = 30110090, truncated to 10000*/ String.fromCharCode(0x40,0x1A,0x00,0x00,0x80,....

        executeAction(stringIDToTypeID("displace"), d, DialogModes.NO);

TOPICS
Actions and scripting

Views

812

Likes

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

correct answers 1 Correct Answer

Adobe Community Professional , Jul 30, 2019 Jul 30, 2019
I made some changes to the script, as it failed when I restarted PS. I made it so that it got the path of the displacement smartobject layer and inserted that into the function that runs the displacement:#target photoshopvar doc = activeDocument;var curLayer = doc.activeLayer;var disMap = doc.layers.getByName('displace test');doc.activeLayer = disMap;editSO ();var disDoc = activeDocument;var disFile = disDoc.path +'/' + disDoc.name;app.activeDocument = doc;doc.activeLayer = curLayer;editDis (dis...

Likes

Translate

Translate
Adobe Community Professional ,
Jul 30, 2019 Jul 30, 2019

Copy link to clipboard

Copied

I don't have two computers to try this, so in theory, you should be able to embed the displacement map into your file. Would would then need to open that smart object, by double clicking on the layer icon. You could then use scriptListener to record making the displacement map, as in tnn e code that you have, or try and use that code, but you will need to change the path on both ways. Smart objects are opened in the temp file of that particular user, so you have to use the tilde symbol to point to the user's folder. So the following script will edit a smartObject with an embedded displacement map. Note in line 48 that I use the ~ to direct to the user's temp folder. In line 4 you need to name the SO layer that has your displacement map. In lines 36 and 38 are the values for displacement. You can put variables there and make a UI to replace them. Here is my screen shot of my setup:

#target photoshop

var doc = activeDocument;

var curLayer = doc.activeLayer;

var disMap = doc.layers.getByName('displace test');

editSO ();

var disDoc = activeDocument;

app.activeDocument = doc;

doc.activeLayer = curLayer;

editDis ();

function editSO(){

    var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );

        var desc3 = new ActionDescriptor();

    executeAction( idplacedLayerEditContents, desc3, DialogModes.NO );  

    }

editDis ()

function editDis(){

    var idsetd = charIDToTypeID( "setd" );

        var desc9 = new ActionDescriptor();

        var idnull = charIDToTypeID( "null" );

            var ref3 = new ActionReference();

            var idfilterFX = stringIDToTypeID( "filterFX" );

            ref3.putIndex( idfilterFX, 1 );

            var idLyr = charIDToTypeID( "Lyr " );

            var idOrdn = charIDToTypeID( "Ordn" );

            var idTrgt = charIDToTypeID( "Trgt" );

            ref3.putEnumerated( idLyr, idOrdn, idTrgt );

        desc9.putReference( idnull, ref3 );

        var idfilterFX = stringIDToTypeID( "filterFX" );

            var desc10 = new ActionDescriptor();

            var idFltr = charIDToTypeID( "Fltr" );

                var desc11 = new ActionDescriptor();

                var idHrzS = charIDToTypeID( "HrzS" );

                desc11.putInteger( idHrzS, 10 );

                var idVrtS = charIDToTypeID( "VrtS" );

                desc11.putInteger( idVrtS, 10 );

                var idDspM = charIDToTypeID( "DspM" );

                var idDspM = charIDToTypeID( "DspM" );

                var idStrF = charIDToTypeID( "StrF" );

                desc11.putEnumerated( idDspM, idDspM, idStrF );

                var idUndA = charIDToTypeID( "UndA" );

                var idUndA = charIDToTypeID( "UndA" );

                var idRptE = charIDToTypeID( "RptE" );

                desc11.putEnumerated( idUndA, idUndA, idRptE );

                var idDspF = charIDToTypeID( "DspF" );

                desc11.putPath( idDspF, new File( "~/AppData/Local/Temp/displace test1.psd" ) );

                var idEmbF = charIDToTypeID( "EmbF" );

                desc11.putBoolean( idEmbF, true );

                var idDspD = charIDToTypeID( "DspD" );   

            var idDspl = charIDToTypeID( "Dspl" );

            desc10.putObject( idFltr, idDspl, desc11 );

        var idfilterFX = stringIDToTypeID( "filterFX" );

        desc9.putObject( idfilterFX, idfilterFX, desc10 );

    executeAction( idsetd, desc9, DialogModes.NO );

   

    }

Here's after I run my script. Note that the a the SO displacement file has been opened.

Likes

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 Professional ,
Jul 30, 2019 Jul 30, 2019

Copy link to clipboard

Copied

I made some changes to the script, as it failed when I restarted PS. I made it so that it got the path of the displacement smartobject layer and inserted that into the function that runs the displacement:

#target photoshop

var doc = activeDocument;

var curLayer = doc.activeLayer;

var disMap = doc.layers.getByName('displace test');

doc.activeLayer = disMap;

editSO ();

var disDoc = activeDocument;

var disFile = disDoc.path +'/' + disDoc.name;

app.activeDocument = doc;

doc.activeLayer = curLayer;

editDis (disFile)

function editSO(){

    var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );

        var desc3 = new ActionDescriptor();

    executeAction( idplacedLayerEditContents, desc3, DialogModes.NO );  

    }

function editDis(dMapFile){

    var idsetd = charIDToTypeID( "setd" );

        var desc9 = new ActionDescriptor();

        var idnull = charIDToTypeID( "null" );

            var ref3 = new ActionReference();

            var idfilterFX = stringIDToTypeID( "filterFX" );

            ref3.putIndex( idfilterFX, 1 );

            var idLyr = charIDToTypeID( "Lyr " );

            var idOrdn = charIDToTypeID( "Ordn" );

            var idTrgt = charIDToTypeID( "Trgt" );

            ref3.putEnumerated( idLyr, idOrdn, idTrgt );

        desc9.putReference( idnull, ref3 );

        var idfilterFX = stringIDToTypeID( "filterFX" );

            var desc10 = new ActionDescriptor();

            var idFltr = charIDToTypeID( "Fltr" );

                var desc11 = new ActionDescriptor();

                var idHrzS = charIDToTypeID( "HrzS" );

                desc11.putInteger( idHrzS, 40 );

                var idVrtS = charIDToTypeID( "VrtS" );

                desc11.putInteger( idVrtS, 40 );

                var idDspM = charIDToTypeID( "DspM" );

                var idDspM = charIDToTypeID( "DspM" );

                var idStrF = charIDToTypeID( "StrF" );

                desc11.putEnumerated( idDspM, idDspM, idStrF );

                var idUndA = charIDToTypeID( "UndA" );

                var idUndA = charIDToTypeID( "UndA" );

                var idRptE = charIDToTypeID( "RptE" );

                desc11.putEnumerated( idUndA, idUndA, idRptE );

                var idDspF = charIDToTypeID( "DspF" );

                desc11.putPath( idDspF, new File( dMapFile ) );

                var idEmbF = charIDToTypeID( "EmbF" );

                desc11.putBoolean( idEmbF, true );

                var idDspD = charIDToTypeID( "DspD" );   

            var idDspl = charIDToTypeID( "Dspl" );

            desc10.putObject( idFltr, idDspl, desc11 );

        var idfilterFX = stringIDToTypeID( "filterFX" );

        desc9.putObject( idfilterFX, idfilterFX, desc10 );

    executeAction( idsetd, desc9, DialogModes.NO );

   

    }

Likes

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
Explorer ,
Jun 07, 2021 Jun 07, 2021

Copy link to clipboard

Copied

LATEST

Hello Chuck,

 

As I understand, the script should create a displacement map from a layer named "displace test" that represents the reference map for the image that is above as in your example but I am getting  the following error 8800 whenever I load the script:

The object "filter effects 1 of current layer" is not currently available.

 

Here is an image to see what I have done so far:

Untitled.jpg

Thank you,

Damian

Likes

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