Skip to main content
Participating Frequently
November 12, 2023
Answered

[JS] Resize layers with a specific interpolation method?

  • November 12, 2023
  • 2 replies
  • 395 views

Hi,

Is there a way to resize layers with a specific interpolation method in a script?

I tried to temporary change the interpolation settings in preferences within the script, but it doesn't work.

app.preferences.interpolation = ResampleMethod.BICUBIC;
firstLayer.resize(10, 10, AnchorPosition.TOPLEFT);
app.preferences.interpolation = ResampleMethod.NEARESTNEIGHBOR;
secondLayer.resize(10, 10, AnchorPosition.TOPLEFT);

They both ended up being resized with a "Nearest Neigbor" method somehow.

Is there any alternative?

This topic has been closed for replies.
Correct answer Stephen Marsh

Curious!

 

The alternative to DOM code is Action Manager (AM):

 

transformLayer(10, 10, true);

function transformLayer(width, height, linked) {
	function s2t(s) {
        return app.stringIDToTypeID(s);
    }
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSCorner0" )); // 0 = upper left
	descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), 0 ); // horizontal
	descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), 0 ); // vertical
	descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
	descriptor.putUnitDouble( s2t( "width" ), s2t( "percentUnit" ), width ); // % value
	descriptor.putUnitDouble( s2t( "height" ), s2t( "percentUnit" ), height ); // % value
	descriptor.putBoolean( s2t( "linked" ), linked ); // boolean
	descriptor.putEnumerated( s2t( "interfaceIconFrameDimmed" ), s2t( "interpolationType" ), s2t( "bicubic" )); // "nearestNeighbor"
    executeAction(s2t("transform"), descriptor, DialogModes.NO);
    
    //    QCSCorner:
    //
    //    0 - - - - - - - - - - - - - - - - 1
    //    |                                 |
    //    |                                 |
    //    |               4                 |
    //    |                                 |
    //    |                                 |
    //    3 - - - - - - - - - - - - - - - - 2

}

2 replies

Stephen Marsh
Community Expert
Community Expert
November 20, 2023

An alternative would be to turn the layer into a Smart Object. Edit the Smart Object and use Image > Image Size to resize to a target pixel image size and interpolation method, then close/save the Smart Object and or convert the SO back to a standard layer.

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
November 13, 2023

Curious!

 

The alternative to DOM code is Action Manager (AM):

 

transformLayer(10, 10, true);

function transformLayer(width, height, linked) {
	function s2t(s) {
        return app.stringIDToTypeID(s);
    }
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSCorner0" )); // 0 = upper left
	descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), 0 ); // horizontal
	descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), 0 ); // vertical
	descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
	descriptor.putUnitDouble( s2t( "width" ), s2t( "percentUnit" ), width ); // % value
	descriptor.putUnitDouble( s2t( "height" ), s2t( "percentUnit" ), height ); // % value
	descriptor.putBoolean( s2t( "linked" ), linked ); // boolean
	descriptor.putEnumerated( s2t( "interfaceIconFrameDimmed" ), s2t( "interpolationType" ), s2t( "bicubic" )); // "nearestNeighbor"
    executeAction(s2t("transform"), descriptor, DialogModes.NO);
    
    //    QCSCorner:
    //
    //    0 - - - - - - - - - - - - - - - - 1
    //    |                                 |
    //    |                                 |
    //    |               4                 |
    //    |                                 |
    //    |                                 |
    //    3 - - - - - - - - - - - - - - - - 2

}
NoxonAuthor
Participating Frequently
November 20, 2023

Hi Stephen,

 

Sorry for the late answer, I didn't take the time to work on this project since.

The script seems to indeed use the right interpolation type when I use it to resize a layer, so this is great!

But your example seems to only use percent units for the resizing. Is there any way we can use pixels units instead?
I tried to copy the "pixelsUnit" value you set for the horizontal and vertical parameters in the height and width parameters, but it still rescale it with percent units somehow.

 

In this script for example, the layers will be resized by 32% instead of 32x32px:

 

try {
    var doc = app.activeDocument;
    var originalLayer = doc.activeLayer; // (We assume it is always a square image)

	var bicubicResizedLayer = originalLayer.duplicate();
	doc.activeLayer = bicubicResizedLayer;
	transformLayer(32, 32, "bicubic")
	
	var neighborResizedLayer = originalLayer.duplicate();
	doc.activeLayer = neighborResizedLayer;
	transformLayer(32, 32, "nearestNeighbor")
} catch (e) {
    alert("Error : " + e.toString());
}

function transformLayer(width, height, interpolationType) {
	function s2t(s) {
        return app.stringIDToTypeID(s);
    }
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSCorner0" )); // 0 = upper left
	descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), 0 ); // horizontal
	descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), 0 ); // vertical
	descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
	descriptor.putUnitDouble( s2t( "width" ), s2t( "pixelUnit" ), width );
	descriptor.putUnitDouble( s2t( "height" ), s2t( "pixelUnit" ), height );
	descriptor.putBoolean( s2t( "linked" ), true );
	descriptor.putEnumerated( s2t( "interfaceIconFrameDimmed" ), s2t( "interpolationType" ), s2t( interpolationType )); // "bicubic" / "nearestNeighbor"
    executeAction(s2t("transform"), descriptor, DialogModes.NO);
}

 

 

NoxonAuthor
Participating Frequently
November 20, 2023

Sorry in this example I let "pixelUnits" instead of "pixelsUnits". I can't edit my answer, but I tried both to be sure.