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

javascript to create a pattern fill layer

Community Beginner ,
Apr 22, 2023 Apr 22, 2023

Copy link to clipboard

Copied

I'm using scripting (Javascript) to automate batch operations with Photoshop. I am creating patterns using "Define pattern" (this part is working).

 

However, I have been unable to figure out how to, from a script, create a fill pattern layer with that defined pattern and have it apply to the layer beneath (which is the top layer of the psd file).

 

Do folks have experience with this, or are you able to figure out a solution? The scripting reference is very... challenging... so I've been using GPT-4 to try to generate code for this, but nothing has worked.

TOPICS
Actions and scripting

Views

1.5K

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 , Apr 22, 2023 Apr 22, 2023

@default29518248cmwmul 

 

The previous code was a standard pattern fill, I missed that you mentioned a pattern fill layer, so here is the code:

 

makePatternFillLayer("Tree Tile 4", "92150a0d-bc3e-9349-adc8-869fb042a4b0");

function makePatternFillLayer(patternName, patternID) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var descriptor3 = new ActionDescriptor();
	var descriptor4 = new Actio
...

Votes

Translate

Translate
Adobe
Community Beginner ,
Apr 22, 2023 Apr 22, 2023

Copy link to clipboard

Copied

In the 2020 documentation, which is the latest I'm able to fine, it describes being able to set the "kind" for a new empty layer that you've created. However, when I do this in Photoshop 2023, it throws an error, saying that "kind" can only be set to text or normal, which seems like a pretty ruthless limitation:
Error 8193: You can only change the layer's kind to text or normal.

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 Beginner ,
Apr 22, 2023 Apr 22, 2023

Copy link to clipboard

Copied

Wait a sec... is what happened is that Adobe nerfed the scripting capabilities in order to force people into using the developer cloud APIs and paying for them?

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 ,
Apr 22, 2023 Apr 22, 2023

Copy link to clipboard

Copied

@default29518248cmwmul 

 

No need for wild conspiracy theories... Photoshop's DOM simply doesn't cover every single feature of Photoshop. Many operations require the use of Action Manger (AM) code, while some other things are simply not possible. For many, the most accessible way to get AM code is to record various operations via the ScriptingListener plug-in.

 

Here is an example of the raw output:

 

var idfill = stringIDToTypeID( "fill" );
    var desc250 = new ActionDescriptor();
    var idusing = stringIDToTypeID( "using" );
    var idfillContents = stringIDToTypeID( "fillContents" );
    var idpattern = stringIDToTypeID( "pattern" );
    desc250.putEnumerated( idusing, idfillContents, idpattern );
    var idpattern = stringIDToTypeID( "pattern" );
        var desc251 = new ActionDescriptor();
        var idname = stringIDToTypeID( "name" );
        desc251.putString( idname, """Tree Tile 4""" );
        var idID = stringIDToTypeID( "ID" );
        desc251.putString( idID, """92150a0d-bc3e-9349-adc8-869fb042a4b0""" );
    var idpattern = stringIDToTypeID( "pattern" );
    desc250.putObject( idpattern, idpattern, desc251 );
    var idopacity = stringIDToTypeID( "opacity" );
    var idpercentUnit = stringIDToTypeID( "percentUnit" );
    desc250.putUnitDouble( idopacity, idpercentUnit, 100.000000 );
    var idmode = stringIDToTypeID( "mode" );
    var idblendMode = stringIDToTypeID( "blendMode" );
    var idnormal = stringIDToTypeID( "normal" );
    desc250.putEnumerated( idmode, idblendMode, idnormal );
executeAction( idfill, desc250, DialogModes.NO );

 

The following code has been "cleaned" and put into a function with parameters put into the function call.

 

patternFill("Tree Tile 4", "92150a0d-bc3e-9349-adc8-869fb042a4b0");

function patternFill(patternName, patternID) {
	function s2t(s) {
        return app.stringIDToTypeID(s);
    }
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	descriptor.putEnumerated( s2t( "using" ), s2t( "fillContents" ), s2t( "pattern" ));
	descriptor2.putString( s2t( "name" ), patternName );
	descriptor2.putString( s2t( "ID" ), patternID );
	descriptor.putObject( s2t( "pattern" ), s2t( "pattern" ), descriptor2 );
	descriptor.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
	descriptor.putEnumerated( s2t( "mode" ), s2t( "blendMode" ), s2t( "normal" ));
	executeAction( s2t( "fill" ), descriptor, 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
Community Expert ,
Apr 22, 2023 Apr 22, 2023

Copy link to clipboard

Copied

@default29518248cmwmul 

 

The previous code was a standard pattern fill, I missed that you mentioned a pattern fill layer, so here is the code:

 

makePatternFillLayer("Tree Tile 4", "92150a0d-bc3e-9349-adc8-869fb042a4b0");

function makePatternFillLayer(patternName, patternID) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var descriptor3 = new ActionDescriptor();
	var descriptor4 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putClass( s2t( "contentLayer" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor4.putString( s2t( "name" ), patternName );
	descriptor4.putString( s2t( "ID" ), patternID );
	descriptor3.putObject( s2t( "pattern" ), s2t( "pattern" ), descriptor4 );
	descriptor2.putObject( s2t( "type" ), s2t( "patternLayer" ), descriptor3 );
	descriptor.putObject( s2t( "using" ), s2t( "contentLayer" ), descriptor2 );
	executeAction( s2t( "make" ), descriptor, 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
Community Beginner ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

As I'm automating this pattern generation, I can make the "name" for the pattern, but I'm not sure what's required for the ID. I assume I can't reuse the same serial number; is there some generator I should be using in my script?

 

Thank you very much for the help!

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 Beginner ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

Haha I need to be able to delete posts. I got confused because I ended up taking a totally different route because I wasn't able to get this working last weekend. Let me sort my sanity out and try this. Thanks!

 

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 Beginner ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

Works great! Turns out the PatternID is not a required property to get passed in, so I was able to just do:

makePatternFillLayer("Tree Tile 4");

function makePatternFillLayer(patternName) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var descriptor3 = new ActionDescriptor();
	var descriptor4 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putClass( s2t( "contentLayer" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor4.putString( s2t( "name" ), patternName );
	descriptor3.putObject( s2t( "pattern" ), s2t( "pattern" ), descriptor4 );
	descriptor2.putObject( s2t( "type" ), s2t( "patternLayer" ), descriptor3 );
	descriptor.putObject( s2t( "using" ), s2t( "contentLayer" ), descriptor2 );
	executeAction( s2t( "make" ), descriptor, DialogModes.NO );
}

Which is good, since getting the PatternID was going to be yet another mini-odyssey for this newbie.

Thank you also for the link to ScriptingListener, that's a nice packager.

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 Beginner ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

LATEST

Ah, I meant "cleaner".

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 ,
Apr 25, 2023 Apr 25, 2023

Copy link to clipboard

Copied

@default29518248cmwmul 

 

So how did the code go?

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