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

How to Create a Small Script?

Aug 15, 2021 Aug 15, 2021

Hey everyone,

 

For those who make scripts for Photoshop, I was wondering if you could make me a really small script to change a pattern. 

 

I'm editing a large amount of PSDs in batch to quickly change a Layer Style Pattern, but which will also maintain the scale that the current pattern is at. If you change a pattern using an action, it does not save the scale of the current pattern even though it is just a different colouration of the same pattern. If I did this same thing with inside Photoshop, not using an action, there is no problem with changing a pattern, and it doesn't affect the scale at all. 

The steps should be simple:
- get layer named 'Pattern' 

- get layer pattern scale and save as a variable ? (I'm not sure if this is an available variable to get nor if it's needed)

- change layer pattern

- set scale to saved variable

 

Opening and saving is dealt with by bridge, it's just the small action I need to replace with a script that doesn't affect the scale of patterns, and just changes it. 

TOPICS
Actions and scripting , Windows
1.1K
Translate
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

Mentor , Aug 15, 2021 Aug 15, 2021

Below you see 2 scripts. Copy the code, save each one separately with the jsx extension (name the files as you like), place the files in the Photoshop presets folder. Restart Photoshop. These files will appear in the scripts menu.

 

The first script gets the scale of the pattern of the current layer and writes it to the layer's metadata (it will be stored with the layer even after you save and reopen the file or copy layer to another document). The second script reads the scale of the pattern from

...
Translate
Adobe
Aug 15, 2021 Aug 15, 2021

It could also be for just a pattern fill layer, it doesn't have to be a layer style...

Again, the problem with actions is the scale is a set value that will be a constant. And I need to the scale to change between each PSD since it's a different value.
Scale Example.JPG

Translate
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 ,
Aug 15, 2021 Aug 15, 2021

Are all you patterns created form the same size canvas  and have design that have object with similar number of pixels.   If your patters do not have the same Aspect Ration  no mater what percent scale you set the the patterns will tile differently.  

 

A script cans get a layers bounds to the know a layers location and a get the document bounds and document print resolution with ease.  With Action manager code a  script can mostly likely get the size of a pattern.  With this information you may be able to calculate some scale percentage  for the pattern to fill the layer so the Paters scaled the way you want it scaled for a particulate document canvas size and print resolution.

JJMack
Translate
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
Aug 15, 2021 Aug 15, 2021

All of the patterns have the same aspect ratio and pixel sizing.The only difference between the patterns is in colour. 
When you change a patterns fill in Photoshop by clicking another pattern, all it does is change the 'Name' and 'ID' variables and doesn't touch the scale. This is exactly what I want the script to do since the action is incapable of this.

Translate
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
Mentor ,
Aug 15, 2021 Aug 15, 2021

Below you see 2 scripts. Copy the code, save each one separately with the jsx extension (name the files as you like), place the files in the Photoshop presets folder. Restart Photoshop. These files will appear in the scripts menu.

 

The first script gets the scale of the pattern of the current layer and writes it to the layer's metadata (it will be stored with the layer even after you save and reopen the file or copy layer to another document). The second script reads the scale of the pattern from the metadata of the current layer and assigns it.

I think it's clear how to use it - start recording the action, first record the launch of the first script (it will receive and save the scale value for the selected layer), then assign the pattern you need, then record the call to the second script (it will adjust the scale by reading the value written on the previous step). You can also use manual launch of scripts if you need to save and later return to the saved scale.

2021-08-15_23-46-19.png

 

Script 1: Save pattern scale to layer metadata.jsx

 

#target photoshop

var lr = new AM('layer'),
    meta = new LayerMetadata('pattern', 'scale');

if (lr.hasProperty('adjustment')) {
    var adj = lr.convertToObject(lr.getProperty(p = 'adjustment'), p)
    for (o in adj) {
        if (adj[o]._obj == 'patternLayer') {
            var scale = adj[o].scale ? adj[o].scale._value : 100;
            meta.set(activeDocument.activeLayer, 'fill', scale)
            break;
        }
    }
}

if (lr.hasProperty('layerEffects')) {
    var fx = lr.convertToObject(lr.getProperty(p = 'layerEffects').value, 'patternFill')
    if (fx) {
        var scale = fx.scale ? fx.scale._value : 100;
        meta.set(activeDocument.activeLayer, 'fx', scale)
    }
}

function LayerMetadata(customNamespace, prefix) {
    if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript')

    this.set = function (layerObj, key, value) {
        try {
            xmpMeta = new XMPMeta(layerObj.xmpMetadata.rawData)
        } catch (e) { xmpMeta = new XMPMeta() }

        XMPMeta.registerNamespace(customNamespace, prefix)
        xmpMeta.setProperty(customNamespace, key, value)
        layerObj.xmpMetadata.rawData = xmpMeta.serialize()
        return ""
    }

    this.get = function (layerObj, key) {
        try {
            xmpMeta = new XMPMeta(layerObj.xmpMetadata.rawData)
            var data = xmpMeta.getProperty(customNamespace, key)
        } catch (e) { }
        return data == undefined ? "" : data.value
    }
}

function AM(target) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;

    target = target ? s2t(target) : null;

    this.getProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        return getDescValue(executeActionGet(r), property)
    }

    this.hasProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
            : r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        return executeActionGet(r).hasKey(property)
    }

    this.convertToObject = function (obj, key) {
        var d = new ActionDescriptor();
        switch (obj.typename) {
            case 'ActionList': d.putList(s2t(key), obj); break;
            case 'ActionDescriptor': d = obj; break;
        }
        (desc = new ActionDescriptor()).putObject(s2t('object'), s2t('json'), d);
        eval('var o = ' + executeAction(s2t('convertJSONdescriptor'), desc).getString(s2t('json')));
        return o[key]
    }

    function getDescValue(d, p) {
        switch (d.getType(p)) {
            case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(p)), value: d.getObjectValue(p) };
            case DescValueType.LISTTYPE: return d.getList(p);
            case DescValueType.REFERENCETYPE: return d.getReference(p);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
            case DescValueType.STRINGTYPE: return d.getString(p);
            case DescValueType.INTEGERTYPE: return d.getInteger(p);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
            case DescValueType.DOUBLETYPE: return d.getDouble(p);
            case DescValueType.ALIASTYPE: return d.getPath(p);
            case DescValueType.CLASSTYPE: return d.getClass(p);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
            case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(p)), value: t2s(d.getEnumerationValue(p)) };
            default: break;
        };
    }
}

 

Script 2: Get pattern scale from layer metadata.jsx

 

#target photoshop

var lr = new AM('layer'),
    meta = new LayerMetadata('pattern', 'scale');

if (lr.hasProperty('adjustment')) {
    var adj = lr.convertToObject(lr.getProperty(p = 'adjustment'), p)
    for (o in adj) {
        if (adj[o]._obj == 'patternLayer') {
            var scale = meta.get(activeDocument.activeLayer, 'fill')
            if (scale) {
                $.writeln(scale)
                lr.setAdjustmentFillScale(lr.getProperty(p), Number(scale))
            }
            break;
        }
    }
}

if (lr.hasProperty('layerEffects')) {
    var fx = lr.convertToObject(lr.getProperty(p = 'layerEffects').value, 'patternFill')
    if (fx) {
        var scale = meta.get(activeDocument.activeLayer, 'fx')
        if (scale) {
            $.writeln(scale)
            lr.setFxFillScale(lr.getProperty(p).value, Number(scale))
        }

    }
}

function LayerMetadata(customNamespace, prefix) {
    if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript')

    this.set = function (layerObj, key, value) {
        try {
            xmpMeta = new XMPMeta(layerObj.xmpMetadata.rawData)
        } catch (e) { xmpMeta = new XMPMeta() }

        XMPMeta.registerNamespace(customNamespace, prefix)
        xmpMeta.setProperty(customNamespace, key, value)
        layerObj.xmpMetadata.rawData = xmpMeta.serialize()
    }

    this.get = function (layerObj, key) {
        try {
            xmpMeta = new XMPMeta(layerObj.xmpMetadata.rawData)
            var data = xmpMeta.getProperty(customNamespace, key)
        } catch (e) { }
        return data == undefined ? "" : data.value

    }
}

function AM(target) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;

    target = target ? s2t(target) : null;

    this.getProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        return getDescValue(executeActionGet(r), property)
    }

    this.hasProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
            : r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        return executeActionGet(r).hasKey(property)
    }

    this.setAdjustmentFillScale = function (list, scale) {
        for (var i = 0; i < list.count; i++) {
            if (t2s(list.getObjectType(i)) == 'patternLayer') {
                var fill = list.getObjectValue(i)
                fill.putUnitDouble(s2t('scale'), s2t('percentUnit'), scale)
            }
        }
        (r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
        (d = new ActionDescriptor()).putReference(s2t("null"), r);
        d.putObject(s2t("to"), s2t("patternLayer"), fill);
        executeAction(s2t("set"), d, DialogModes.NO);

    }

    this.setFxFillScale = function (desc, scale) {
        s2t = stringIDToTypeID;

        var fill = desc.getObjectValue(s2t("patternFill"));
        fill.putUnitDouble(s2t('scale'), s2t('percentUnit'), scale);

        (r = new ActionReference()).putProperty(s2t("property"), p = s2t("layerEffects"));
        r.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        var fx = executeActionGet(r).getObjectValue(p);
        fx.putObject(s2t("patternFill"), s2t("patternFill"), fill);
        (d = new ActionDescriptor()).putReference(s2t("null"), r);
        d.putObject(s2t("to"), s2t("layerEffects"), fx);
        executeAction(s2t("set"), d, DialogModes.NO);
    }

    this.convertToObject = function (obj, key) {
        var d = new ActionDescriptor();
        switch (obj.typename) {
            case 'ActionList': d.putList(s2t(key), obj); break;
            case 'ActionDescriptor': d = obj; break;
        }
        (desc = new ActionDescriptor()).putObject(s2t('object'), s2t('json'), d);
        eval('var o = ' + executeAction(s2t('convertJSONdescriptor'), desc).getString(s2t('json')));
        return o[key]
    }

    function getDescValue(d, p) {
        switch (d.getType(p)) {
            case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(p)), value: d.getObjectValue(p) };
            case DescValueType.LISTTYPE: return d.getList(p);
            case DescValueType.REFERENCETYPE: return d.getReference(p);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
            case DescValueType.STRINGTYPE: return d.getString(p);
            case DescValueType.INTEGERTYPE: return d.getInteger(p);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
            case DescValueType.DOUBLETYPE: return d.getDouble(p);
            case DescValueType.ALIASTYPE: return d.getPath(p);
            case DescValueType.CLASSTYPE: return d.getClass(p);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
            case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(p)), value: t2s(d.getEnumerationValue(p)) };
            default: break;
        };
    }
}

 

Translate
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
LEGEND ,
Aug 15, 2021 Aug 15, 2021

To Apply Style 'Style 1', you choose it from Styles panel? Then on your screenshot you Set Current Fill Layer, but to do it first it's needed to make Adjustement Pattern Layer?

Translate
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
Mentor ,
Aug 15, 2021 Aug 15, 2021

Yes. It is assumed that the user does not create, but changes the pattern. That is, all the necessary layers have already been created and configured. At least that's how I understood @32621919 

Translate
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
LEGEND ,
Aug 15, 2021 Aug 15, 2021

After actions are created and I want to use them again, what am I supposed to do?

(there is metadata in a layer, but after playing actions I don't see much difference)

Translate
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
Mentor ,
Aug 15, 2021 Aug 15, 2021

I don’t know what patterns you used when checking, perhaps their initial scale was close to each other. Try to manually set the scale value like 500% before save it in metadata

Translate
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
LEGEND ,
Aug 17, 2021 Aug 17, 2021
LATEST

So you use later only last 'get' script action item for another patterns. That I needed to know.

Translate
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
Aug 16, 2021 Aug 16, 2021

@jazz-y Yes, the layers are configured already. On one PSD, the pattern might be 54% scale, on another 98%. However, they are both the same pattern, just different scales. My only objective is to change the pattern while maintaining the scale that is on the current layer for each PSD.
I'm going to read over your script and try it out. Thank you for sharing.

Translate
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
Aug 16, 2021 Aug 16, 2021

After trying out the scripts and action you gave me, it works perfectly. Thank you for this, it's saved a huge amount of time.

Translate
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