javascript - 使用 For 循环时图像未正确对齐

标签 javascript photoshop photoshop-script

我正在制作一个带有各种不同尺寸的图像的贴纸页。 贴纸需要位于半径为 1000 像素的橙色圆圈内。

为了确保对齐正确,我添加了一个测试黑色边框以直观地查看其布局方式。

这就是它的布局。真漂亮。

所以,我认为剧本已经准备好了。我把它投入使用,但现在没有黑色边框了。结果是这样的……

看看右下角是如何裁剪的吗?我觉得这与我的 For 循环代码的“数学”有关,我无法弄清楚...... 这是我的代码:

    // Page 3: Third document. =====================================================
    // Note: Need to re-initialize as the variables are referencing to the previous document.
    //       Error shown: The requested action requires that the target document is the frontmost document.
    var doc = app.activeDocument;
    var layer = doc.activeLayer;
    // Get the variables to work with.
    var width       = doc.width.as('px');
    var height      = doc.height.as('px');
    var bounds      = app.activeDocument.activeLayer.bounds;
    var layerWidth  = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');
    var resolution  = doc.resolution;

    // Create bleed guides.
    doc.guides.add(Direction.HORIZONTAL, bleed);
    doc.guides.add(Direction.VERTICAL, bleed);
    doc.guides.add(Direction.HORIZONTAL, height - bleed);
    doc.guides.add(Direction.VERTICAL, width - bleed);

    // Third auto-page workings.
    // x1 biggest.
    doc.paste();  // Paste the selection.
    doc.activeLayer.translate(0 - width / 4, 0 - height / 4);  // Move layer to the top left corner. First copy.
    var big_copy = doc.activeLayer;  // Copy the selection.
    // x4 mid sized.
    for (var i = 0; i < 2; i++) {
        for (var j = 0; j < 2; j++) {
            copy = doc.activeLayer.duplicate();
            copy.translate(0 + width / 4 * i, (0 + height / 2) + (height / 4 * j));
            copy.resize(50, 50, AnchorPosition.TOPLEFT);
        }
    }
    // Many minis.
    for (var i = 0; i < 3; i++) {
        for (var j = 0; j < 6; j++) {
            copy = big_copy.duplicate();
            copy.translate((0 + width / 2) + (width / 2 / 3 * i), 0 + (height / 6 * j));
            copy.resize(100 / 3, 100 / 3, AnchorPosition.TOPLEFT);
        }
    }

    doc.artLayers.getByName('Background').remove();  // Delete the Background layer.
    mergeVisible();  // Merge visible.
    freeTransform(0, 0, (width - bleed * 2) / width * 100, (height - bleed * 2) / height * 100);  // Resize selection within bleeds.

编辑:[更多信息] 黑色边框在自动化之前与恐龙图像合并。所以,我猜测为什么它能正确处理边框是因为合并图像的尺寸为 1000px x 1000px。当我去掉黑色边框的那一刻,它就破裂了。这可能是由于 anchor 位置......但我不确定。

最佳答案

我稍微修改了您的代码:部分问题是脚本正在合并所有可见图层,并且当某些图层超出文档边界时,它们不是此合并的一部分。所以

  • 在第 67 行,我创建了一个组来包含所有图层
  • 第 75、86 和 97 行,所有重复项都添加到该组中
  • 在第 105 行而不是 mergeVisible() 上,我选择该组并使用 mergeDown() 将其合并
  • 然后稍后进行自由变换,我使用这个新层的边界

结果如下:

enter image description here

和代码:

var maintainAspectRatio; // Set to true to keep aspect ratio.
maintainAspectRatio = true;
if (app.documents.length > 0)
{
    app.activeDocument.suspendHistory('Auto Sheet Maker', 'AutoSheetMaker(' + maintainAspectRatio + ')');
}

function AutoSheetMaker(keepAspect)
{ // keepAspect:Boolean - optional. Default to false.
    // Store the ruler.
    var defaultRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    // Global bleed pixels on all docs.
    bleed = 25;

    // Main master document. =======================================================
    var doc = app.activeDocument;
    var layer = doc.activeLayer;
    // Get the variables to work with.
    var width = doc.width.as('px');
    var height = doc.height.as('px');
    var bounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');
    var resolution = doc.resolution;

    // The saved directory location of the main master document.
    Path = doc.path; // If the document is new there is no doc.path. Error is shown.

    // Main master document workings.
    copy = doc.layerSets["Artwork"].duplicate(); // Duplicate Group layer by name.
    doc.activeLayer = doc.layerSets["Artwork copy"]; // Select Group layer by name.
    doc.activeLayer.merge(); // Merge the selection. In this case, the Group layer.
    var dogbox = 1000; // The region dimensions that's considered in the automation.
    ellipse_selection(height / 2 - dogbox / 2, width / 2 - dogbox / 2, width / 2 + dogbox / 2, height / 2 + dogbox / 2); // Make a circle selection.
    freeTransform(0, 0, width / dogbox * 100, height / dogbox * 100); // Resize selection to fit the whole canvas, ignoring bleeds.
    doc.selection.copy(); // Copy the selection.
    deSelect();
    doc.artLayers.getByName('Artwork copy').remove(); // Delete the Artwork copy layer.

    // =============================================================================

    app.documents.add(width, height, resolution, "layout_debug", NewDocumentMode.CMYK); // Create a new document.

    // Page 3: Third document. =====================================================
    // Note: Need to re-initialize as the variables are referencing to the previous document.
    //       Error shown: The requested action requires that the target document is the frontmost document.
    var doc = app.activeDocument;
    var layer = doc.activeLayer;
    // Get the variables to work with.
    var width = doc.width.as('px');
    var height = doc.height.as('px');
    var bounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');
    var resolution = doc.resolution;

    // Create bleed guides.
    doc.guides.add(Direction.HORIZONTAL, bleed);
    doc.guides.add(Direction.VERTICAL, bleed);
    doc.guides.add(Direction.HORIZONTAL, height - bleed);
    doc.guides.add(Direction.VERTICAL, width - bleed);

    /////////////////////////////////////////////////////////////////////////////////////
    // new: creating a group to contain all the layers
    var layersGroup = doc.layerSets.add();

    // Third auto-page workings.
    // x1 biggest.
    doc.paste(); // Paste the selection.
    doc.activeLayer.resize(50, 50, AnchorPosition.MIDDLECENTER); // Resize the pasted layer by 50%.
    doc.activeLayer.translate(0 - width / 4, 0 - height / 4); // Move layer to the top left corner. First copy.

    doc.activeLayer.move(layersGroup, ElementPlacement.INSIDE); // new: adding active layer to the group

    var big_copy = doc.activeLayer; // Copy the selection.
    // x4 mid sized.
    for (var i = 0; i < 2; i++)
    {
        for (var j = 0; j < 2; j++)
        {
            copy = doc.activeLayer.duplicate();
            copy.translate(0 + width / 4 * i, (0 + height / 2) + (height / 4 * j));
            copy.resize(50, 50, AnchorPosition.TOPLEFT);
            copy.move(layersGroup, ElementPlacement.INSIDE); // new: adding active layer to the group
        }
    }
    // Many minis.
    for (var i = 0; i < 3; i++)
    {
        for (var j = 0; j < 6; j++)
        {
            copy = big_copy.duplicate();
            copy.translate((0 + width / 2) + (width / 2 / 3 * i), 0 + (height / 6 * j));
            copy.resize(100 / 3, 100 / 3, AnchorPosition.TOPLEFT);
            copy.move(layersGroup, ElementPlacement.INSIDE); // new: adding active layer to the group
        }
    }

    doc.artLayers.getByName('Background').remove(); // Delete the Background layer.

    /////////////////////////////////////////////////////////////////////////////////////
    // new: selecting the group and merging it down
    doc.activeLayer = layersGroup;
    mergeDown();

    /////////////////////////////////////////////////////////////////////////////////////
    // new: getting coords of the resulting merge layer to transform those
    var bounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');

    freeTransform((-bounds[0].as('px') + bleed), (-bounds[1].as('px') + bleed), (layerWidth - bleed * 2) / layerWidth * 100, (layerHeight - bleed * 2) / layerHeight * 100); // Resize selection within bleeds.

    // =============================================================================

    // Restore the ruler.
    app.preferences.rulerUnits = defaultRulerUnits;

    alert("Script automation completed!");
}

// Ellipse marquee selection.
function ellipse_selection(top, left, right, bottom)
{
    var id1 = charIDToTypeID("setd");
    var desc1 = new ActionDescriptor();
    var id2 = charIDToTypeID("null");
    var ref1 = new ActionReference();
    var id3 = charIDToTypeID("Chnl");
    var id4 = charIDToTypeID("fsel");
    ref1.putProperty(id3, id4);
    desc1.putReference(id2, ref1);
    var id5 = charIDToTypeID("T   ");
    var desc2 = new ActionDescriptor();
    var id6 = charIDToTypeID("Top ");
    var id7 = charIDToTypeID("#Pxl");
    desc2.putUnitDouble(id6, id7, top); //top
    var id8 = charIDToTypeID("Left");
    var id9 = charIDToTypeID("#Pxl");
    desc2.putUnitDouble(id8, id9, left); //left
    var id10 = charIDToTypeID("Btom");
    var id11 = charIDToTypeID("#Pxl");
    desc2.putUnitDouble(id10, id11, bottom); //bottom
    var id12 = charIDToTypeID("Rght");
    var id13 = charIDToTypeID("#Pxl");
    desc2.putUnitDouble(id12, id13, right); //right
    var id14 = charIDToTypeID("Elps");
    desc1.putObject(id5, id14, desc2);
    var id15 = charIDToTypeID("AntA");
    desc1.putBoolean(id15, true);
    executeAction(id1, desc1, DialogModes.NO);
}
// Deselect selection.
function deSelect()
{
    var idsetd = charIDToTypeID("setd");
    var desc19 = new ActionDescriptor();
    var idnull = charIDToTypeID("null");
    var ref5 = new ActionReference();
    var idChnl = charIDToTypeID("Chnl");
    var idfsel = charIDToTypeID("fsel");
    ref5.putProperty(idChnl, idfsel);
    desc19.putReference(idnull, ref5);
    var idT = charIDToTypeID("T   ");
    var idOrdn = charIDToTypeID("Ordn");
    var idNone = charIDToTypeID("None");
    desc19.putEnumerated(idT, idOrdn, idNone);
    executeAction(idsetd, desc19, DialogModes.NO);
}
// Free transform ('Ctrl' + 't' method).
function freeTransform(top, left, width, height)
{
    var idTrnf = charIDToTypeID("Trnf");
    var desc92 = new ActionDescriptor();
    var idnull = charIDToTypeID("null");
    var ref23 = new ActionReference();
    var idLyr = charIDToTypeID("Lyr ");
    var idOrdn = charIDToTypeID("Ordn");
    var idTrgt = charIDToTypeID("Trgt");
    ref23.putEnumerated(idLyr, idOrdn, idTrgt);
    desc92.putReference(idnull, ref23);
    var idFTcs = charIDToTypeID("FTcs");
    var idQCSt = charIDToTypeID("QCSt");
    var idQcsa = charIDToTypeID("Qcsa");
    desc92.putEnumerated(idFTcs, idQCSt, idQcsa);
    var idOfst = charIDToTypeID("Ofst");
    var desc93 = new ActionDescriptor();
    var idHrzn = charIDToTypeID("Hrzn");
    var idPxl = charIDToTypeID("#Pxl");
    desc93.putUnitDouble(idHrzn, idPxl, top);
    var idVrtc = charIDToTypeID("Vrtc");
    var idPxl = charIDToTypeID("#Pxl");
    desc93.putUnitDouble(idVrtc, idPxl, left);
    var idOfst = charIDToTypeID("Ofst");
    desc92.putObject(idOfst, idOfst, desc93);
    var idWdth = charIDToTypeID("Wdth");
    var idPrc = charIDToTypeID("#Prc");
    desc92.putUnitDouble(idWdth, idPrc, height);
    var idHght = charIDToTypeID("Hght");
    var idPrc = charIDToTypeID("#Prc");
    desc92.putUnitDouble(idHght, idPrc, width);
    var idIntr = charIDToTypeID("Intr");
    var idIntp = charIDToTypeID("Intp");
    var idbicubicSharper = stringIDToTypeID("bicubicSharper");
    desc92.putEnumerated(idIntr, idIntp, idbicubicSharper);
    executeAction(idTrnf, desc92, DialogModes.NO);
}
// Merge visible layers.
function mergeVisible()
{
    var idMrgV = charIDToTypeID("MrgV");
    executeAction(idMrgV, undefined, DialogModes.NO);
}

function mergeDown()
{
    var desc = new ActionDescriptor();
    executeAction(charIDToTypeID('Mrg2'), desc, DialogModes.NO);
} // end of mergeDown()

关于javascript - 使用 For 循环时图像未正确对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57857148/

相关文章:

javascript - 为什么我在此函数定义中得到 “Error 25: Expected: ;”?

javascript - VBScript 调用 JavaScript

javascript - jQuery:如何选择所有带有名称的单选按钮?

python - 以编程方式编辑 Photoshop PSD 文本图层

html - 寻找第三方照片库

Photoshop JSX 脚本 - 关闭 Photoshop

javascript - jQuery 中的字符串验证错误

javascript - AngularJS - Controller 功能不适用于/ng-click

javascript - ES6模块: imported constants are undefined at first; they become available later