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

[JS] Resize layers with a specific interpolation method?

Community Beginner ,
Nov 12, 2023 Nov 12, 2023

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?

TOPICS
Actions and scripting , Windows
288
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

Community Expert , Nov 12, 2023 Nov 12, 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( s2
...
Translate
Adobe
Community Expert ,
Nov 12, 2023 Nov 12, 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

}
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 Beginner ,
Nov 20, 2023 Nov 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);
}

 

 

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 Beginner ,
Nov 20, 2023 Nov 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.

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 ,
Nov 20, 2023 Nov 20, 2023

AFAIK Action Manager only uses % for the transform.

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 ,
Nov 20, 2023 Nov 20, 2023

layer.resize() takes arguments as percents. You can easily do the math [new size / existing size] to determine percentage.

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 Beginner ,
Nov 20, 2023 Nov 20, 2023

Okay thank you!

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 ,
Nov 20, 2023 Nov 20, 2023
LATEST

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.

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