Duplicate and move element on alpha channel using javascript

Engaged ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

I tried to copy and move some selected element on alpha channel, and i record that script with SL, but i am not sure how to change units in milimeters. For example i want to copy and move element for 50mm to the left, but SL return me -226.771200). How it is possible to improve it or do it in a simpler way?

Screen Shot 2022-08-16 at 10.20.44.png

 

// =======================================================
var idcopyEvent = stringIDToTypeID( "copyEvent" );
    var desc210 = new ActionDescriptor();
    var idcopyHint = stringIDToTypeID( "copyHint" );
    desc210.putString( idcopyHint, """pixels""" );
executeAction( idcopyEvent, desc210, DialogModes.NO );

// =======================================================
var idpaste = stringIDToTypeID( "paste" );
    var desc212 = new ActionDescriptor();
    var idinPlace = stringIDToTypeID( "inPlace" );
    desc212.putBoolean( idinPlace, true );
    var idantiAlias = stringIDToTypeID( "antiAlias" );
    var idantiAliasType = stringIDToTypeID( "antiAliasType" );
    var idantiAliasNone = stringIDToTypeID( "antiAliasNone" );
    desc212.putEnumerated( idantiAlias, idantiAliasType, idantiAliasNone );
    var idas = stringIDToTypeID( "as" );
    var idpixel = stringIDToTypeID( "pixel" );
    desc212.putClass( idas, idpixel );
executeAction( idpaste, desc212, DialogModes.NO );

// =======================================================
var idtransform = stringIDToTypeID( "transform" );
    var desc214 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref14 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref14.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc214.putReference( idnull, ref14 );
    var idfreeTransformCenterState = stringIDToTypeID( "freeTransformCenterState" );
    var idquadCenterState = stringIDToTypeID( "quadCenterState" );
    var idQCSAverage = stringIDToTypeID( "QCSAverage" );
    desc214.putEnumerated( idfreeTransformCenterState, idquadCenterState, idQCSAverage );
    var idoffset = stringIDToTypeID( "offset" );
        var desc215 = new ActionDescriptor();
        var idhorizontal = stringIDToTypeID( "horizontal" );
        var iddistanceUnit = stringIDToTypeID( "distanceUnit" );
        desc215.putUnitDouble( idhorizontal, iddistanceUnit, -226.771200 );
        var idvertical = stringIDToTypeID( "vertical" );
        var iddistanceUnit = stringIDToTypeID( "distanceUnit" );
        desc215.putUnitDouble( idvertical, iddistanceUnit, 0.000000 );
    var idoffset = stringIDToTypeID( "offset" );
    desc214.putObject( idoffset, idoffset, desc215 );
    var idlinked = stringIDToTypeID( "linked" );
    desc214.putBoolean( idlinked, true );
    var idinterfaceIconFrameDimmed = stringIDToTypeID( "interfaceIconFrameDimmed" );
    var idinterpolationType = stringIDToTypeID( "interpolationType" );
    var idbicubic = stringIDToTypeID( "bicubic" );
    desc214.putEnumerated( idinterfaceIconFrameDimmed, idinterpolationType, idbicubic );
executeAction( idtransform, desc214, DialogModes.NO );

 

 

TOPICS
Actions and scripting

Views

137

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

Engaged , Aug 18, 2022 Aug 18, 2022

@Stephen_A_Marsh sorry for misunderstanding, finaly i found a mistake, i combined your code with SL from beginning but i didnt include this post from @jazz-y 

I didnt change line var iddistanceUnit = stringIDToTypeID( "pixelsUnit" ); and because of that i got strange result

Now i change it and here is complete code

 

// Save the rulers and set to px
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Change the value in millimeters as required
var valueInMM = 
...

Likes

Translate

Translate
Community Expert ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

@milevic 

 

As Photoshop uses pixels as the native unit of measure:

(valueInMM * valueInPPI) / 25.4

 

Edit: Code updated, now with the missing parentheses!

 

#target photoshop

// Save the rulers and set to px
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Change the value in millimeters as required
var valueInMM = 50;

// MM to PX
var valueInPPI = activeDocument.resolution;
var roundedValue = Math.round((valueInMM * valueInPPI) / 25.4);

// Select the first alpha channel in an RGB, Lab or CMYK mode file
if (activeDocument.mode === DocumentMode.RGB || activeDocument.mode === DocumentMode.LAB) {
    selectFirstAlphaChannel(3);
} else if (activeDocument.mode === DocumentMode.CMYK) {
    selectFirstAlphaChannel(4);
}

// Negative offset (white on black channel data)
activeDocument.activeLayer.applyOffset( -roundedValue, 0, OffsetUndefinedAreas.WRAPAROUND);
fade(100, "lighten");

// Restore the rulers
app.preferences.rulerUnits = savedRuler;


///// Functions /////
function fade(opacity, blendMode) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	descriptor.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), opacity );
	descriptor.putEnumerated( s2t( "mode" ), s2t( "blendMode" ), s2t( blendMode ));
	executeAction(s2t( "fade" ), descriptor, DialogModes.NO);
}

function selectFirstAlphaChannel(theNo) {
    var theChannel = new Array(app.activeDocument.channels[theNo]);
    app.activeDocument.activeChannels = theChannel;
}

 

 

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
Engaged ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

I got this message

.Screen Shot 2022-08-16 at 13.38.16.png

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
Community Expert ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

@milevic – I originally used DOM code, however, I replaced it with AM code... So I have put the DOM code back in again!

 

I removed it as it was addressing the active layer, it works, it just bugs me that I couldn't target the channel via DOM code.

 

Please try again.

 

P.S. You could always paste in the SL recorded AM code for the offset filter that works for your version of Photoshop, just replace the hard-coded px value for the -roundedValue variable.

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
Engaged ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

Thanks for answering. It works on representative example, but i have some more doubts 🙂

Is it possible to improve:

  • to duplicate and move just selected part of alpha channel
  • often i have more than one alpha channel so it is not always first alpha channel
  • can there be a single script for alpha channels, selections and spot colors - as it is on SL code that i attacheed

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
Community Expert ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

@milevic – (untested) you should be able to change the hard-coded px value in your SL recording to use the variable that I created by multiplying the required value in MM by the document PPI divided by 25.4 MM:

 

(valueInMM * valueInPPI) / 25.4

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
Engaged ,
Aug 17, 2022 Aug 17, 2022

Copy link to clipboard

Copied

I tried with this calculation and it works same on different resolutions

// Change the value in millimeters as required
var valueInMM = 50;
var roundedValue = valueInMM * 2.83464;
// =======================================================
var idcopyEvent = stringIDToTypeID( "copyEvent" );
    var desc210 = new ActionDescriptor();
    var idcopyHint = stringIDToTypeID( "copyHint" );
    desc210.putString( idcopyHint, """pixels""" );
executeAction( idcopyEvent, desc210, DialogModes.NO );

// =======================================================
var idpaste = stringIDToTypeID( "paste" );
    var desc212 = new ActionDescriptor();
    var idinPlace = stringIDToTypeID( "inPlace" );
    desc212.putBoolean( idinPlace, true );
    var idantiAlias = stringIDToTypeID( "antiAlias" );
    var idantiAliasType = stringIDToTypeID( "antiAliasType" );
    var idantiAliasNone = stringIDToTypeID( "antiAliasNone" );
    desc212.putEnumerated( idantiAlias, idantiAliasType, idantiAliasNone );
    var idas = stringIDToTypeID( "as" );
    var idpixel = stringIDToTypeID( "pixel" );
    desc212.putClass( idas, idpixel );
executeAction( idpaste, desc212, DialogModes.NO );

// =======================================================
var idtransform = stringIDToTypeID( "transform" );
    var desc214 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref14 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref14.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc214.putReference( idnull, ref14 );
    var idfreeTransformCenterState = stringIDToTypeID( "freeTransformCenterState" );
    var idquadCenterState = stringIDToTypeID( "quadCenterState" );
    var idQCSAverage = stringIDToTypeID( "QCSAverage" );
    desc214.putEnumerated( idfreeTransformCenterState, idquadCenterState, idQCSAverage );
    var idoffset = stringIDToTypeID( "offset" );
        var desc215 = new ActionDescriptor();
        var idhorizontal = stringIDToTypeID( "horizontal" );
        var iddistanceUnit = stringIDToTypeID( "distanceUnit" );
        desc215.putUnitDouble( idhorizontal, iddistanceUnit, roundedValue);
        var idvertical = stringIDToTypeID( "vertical" );
        var iddistanceUnit = stringIDToTypeID( "distanceUnit" );
        desc215.putUnitDouble( idvertical, iddistanceUnit, 0.000000 );
    var idoffset = stringIDToTypeID( "offset" );
    desc214.putObject( idoffset, idoffset, desc215 );
    var idlinked = stringIDToTypeID( "linked" );
    desc214.putBoolean( idlinked, true );
    var idinterfaceIconFrameDimmed = stringIDToTypeID( "interfaceIconFrameDimmed" );
    var idinterpolationType = stringIDToTypeID( "interpolationType" );
    var idbicubic = stringIDToTypeID( "bicubic" );
    desc214.putEnumerated( idinterfaceIconFrameDimmed, idinterpolationType, idbicubic );
executeAction( idtransform, desc214, 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
Engaged ,
Aug 17, 2022 Aug 17, 2022

Copy link to clipboard

Copied

But i have another issue. This script doesnt work if some group is marked, only works if some layer is marked.

Is it possible to improve this adding some code at beginning which will select any layer in a layera structure?

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
Community Expert ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

This code will select the first artLayer, not layerSet without affecting visibility:

 

if (activeDocument.artLayers[0].visible === false) {
    activeDocument.activeLayer = activeDocument.artLayers[0];
    activeDocument.activeLayer.visible = false;
} else {
    activeDocument.activeLayer = activeDocument.artLayers[0];
}

 

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
Community Expert ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied


@milevic wrote:

I tried with this calculation and it works same on different resolutions

// Change the value in millimeters as required
var valueInMM = 50;
var roundedValue = valueInMM * 2.83464;

 

Hi, you didn't put in a variable for the document PPI resolution:

var valueInPPI = activeDocument.resolution;

As per the original script that I posted and updated with the previously missing parenthesis chars:

// Change the value in millimeters as required
var valueInMM = 50;
// MM to PX
var valueInPPI = activeDocument.resolution;
var roundedValue = Math.round((valueInMM * valueInPPI) / 25.4);

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
Engaged ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

LATEST

@Stephen_A_Marsh sorry for misunderstanding, finaly i found a mistake, i combined your code with SL from beginning but i didnt include this post from @jazz-y 

I didnt change line var iddistanceUnit = stringIDToTypeID( "pixelsUnit" ); and because of that i got strange result

Now i change it and here is complete code

 

// Save the rulers and set to px
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Change the value in millimeters as required
var valueInMM = 50;

// MM to PX
var valueInPPI = activeDocument.resolution;
var roundedValue = Math.round((valueInMM * valueInPPI) / 25.4);

// =======================================================
var idcopyEvent = stringIDToTypeID( "copyEvent" );
    var desc210 = new ActionDescriptor();
    var idcopyHint = stringIDToTypeID( "copyHint" );
    desc210.putString( idcopyHint, """pixels""" );
executeAction( idcopyEvent, desc210, DialogModes.NO );

// =======================================================
var idpaste = stringIDToTypeID( "paste" );
    var desc212 = new ActionDescriptor();
    var idinPlace = stringIDToTypeID( "inPlace" );
    desc212.putBoolean( idinPlace, true );
    var idantiAlias = stringIDToTypeID( "antiAlias" );
    var idantiAliasType = stringIDToTypeID( "antiAliasType" );
    var idantiAliasNone = stringIDToTypeID( "antiAliasNone" );
    desc212.putEnumerated( idantiAlias, idantiAliasType, idantiAliasNone );
    var idas = stringIDToTypeID( "as" );
    var idpixel = stringIDToTypeID( "pixel" );
    desc212.putClass( idas, idpixel );
executeAction( idpaste, desc212, DialogModes.NO );

// =======================================================
var idtransform = stringIDToTypeID( "transform" );
    var desc214 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref14 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref14.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc214.putReference( idnull, ref14 );
    var idfreeTransformCenterState = stringIDToTypeID( "freeTransformCenterState" );
    var idquadCenterState = stringIDToTypeID( "quadCenterState" );
    var idQCSAverage = stringIDToTypeID( "QCSAverage" );
    desc214.putEnumerated( idfreeTransformCenterState, idquadCenterState, idQCSAverage );
    var idoffset = stringIDToTypeID( "offset" );
        var desc215 = new ActionDescriptor();
        var idhorizontal = stringIDToTypeID( "horizontal" );
        var iddistanceUnit = stringIDToTypeID( "pixelsUnit" );
        desc215.putUnitDouble( idhorizontal, iddistanceUnit, roundedValue);
        var idvertical = stringIDToTypeID( "vertical" );
        var iddistanceUnit = stringIDToTypeID( "pixelsUnit" );
        desc215.putUnitDouble( idvertical, iddistanceUnit, 0.000000 );
    var idoffset = stringIDToTypeID( "offset" );
    desc214.putObject( idoffset, idoffset, desc215 );
    var idlinked = stringIDToTypeID( "linked" );
    desc214.putBoolean( idlinked, true );
    var idinterfaceIconFrameDimmed = stringIDToTypeID( "interfaceIconFrameDimmed" );
    var idinterpolationType = stringIDToTypeID( "interpolationType" );
    var idbicubic = stringIDToTypeID( "bicubic" );
    desc214.putEnumerated( idinterfaceIconFrameDimmed, idinterpolationType, idbicubic );
executeAction( idtransform, desc214, 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
Community Expert ,
Aug 16, 2022 Aug 16, 2022

Copy link to clipboard

Copied

distanceUnit for transform in Action Manager means pointsUnit. You can also set it to

 

var iddistanceUnit = stringIDToTypeID( "pixelsUnit" );

 

to set the displacement in pixels.

As far as I remember, other units of measurement (centimetersUnit, inchesUnit, millimetersUnit, etc.) are ignored.

That is, if you need transformation in mm, then you need to make a preliminary recalculation of the values ​​from mm to points or from pixels to points.

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