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

Script to Embed Displacement Map Data, CC2019

Explorer ,
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

1.6K

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

Community Expert , 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 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 (dis

...

Votes

Translate

Translate
Adobe
Community Expert ,
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.

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 ,
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 );

   

    }

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

Copy link to clipboard

Copied

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

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
New Here ,
Nov 15, 2023 Nov 15, 2023

Copy link to clipboard

Copied

LATEST

That is because of some filterfx mentioned in the script. Seems to be some add-in or plug in.

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
New Here ,
May 21, 2022 May 21, 2022

Copy link to clipboard

Copied

I think this doesn't work for PS2022? That would be very helpful if anyone can share the compatible one with the latest ps.

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