如何以编程方式在 photoshop 中添加填充层

how to add a fill layer in photoshop programatically

我的目标是以编程方式定义比例尺,它具有固定长度,但之后可能会被图形设计师更改。

我已经在文档中定义了一个封闭路径:

def addLine(doc):
    
    def point(x, y):
        result      = Dispatch("Photoshop.PathPointInfo")
        result.Kind = 2 # for PsPointKind --> 2 (psCornerPoint)
        result.LeftDirection = result.rightDirection = result.Anchor = (x, y)
        return result

    points = [    
              point(100, 100),
              point(200, 100),
              point(200, 110),
              point(100, 110)
              ]

    lineSubPathArray               = Dispatch("Photoshop.SubPathInfo")
    lineSubPathArray.Operation     = 1 #for PsShapeOperation --> 1 (psShapeAdd
    lineSubPathArray.Closed        = True
    lineSubPathArray.EntireSubPath = points
    
    myPathItem = doc.PathItems.Add("bar-path", [lineSubPathArray])

从这里,我可以将保存的文档加载回 photoshop (CS6),然后手动创建一个形状图层:Layer |新填充层 |纯色 ...

这会产生一个形状图层,类似于我使用线条工具得到的效果,其中的线条实际上是一个矩形,其高度稍后可能会更改。

第一个问题:如何使用API?

创建填充层

其次:我定义了一个100像素宽的矩形,但是我得到了一个418像素宽的矩形。该文档的 doc.application.preferences.rulerUnits 设置为 psPixels (1)。这是为什么?

最后:是否可以将一条线定义为由两个端点定义的真实线并设置其笔画宽度而不是其高度?

这可能有用:

您可以使用 new SolidColor()

定义新颜色
   // define fillColor 
   var fillColor = new SolidColor();
   var myColour = [57, 181,74];
   fillColor.rgb.red   = myColour[0];
   fillColor.rgb.green = myColour[1];
   fillColor.rgb.blue  = myColour[2];

然后通过添加 myPathItem.fillPath(fillColor,ColorBlendMode.NORMAL,100,false,0,true,true);

来填充您的路径
// Switch off any dialog boxes
displayDialogs = DialogModes.NO; // OFF

var originalUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

// call the source document
var srcDoc = app.activeDocument;

create_path("bar-path");

function create_path(linename)
{

   var points = [    
   [100, 100],
   [200, 100],
   [200, 110],
   [100, 110]
   ];


   // create the array of PathPointInfo objects
   var lineArray = new Array();

   for (var i = 0; i < points.length; i++)
   {
      lineArray[i] = new PathPointInfo;
      lineArray[i].kind = PointKind.CORNERPOINT;
      lineArray[i].anchor = points[i];
      lineArray[i].leftDirection = lineArray[i].anchor;
      lineArray[i].rightDirection = lineArray[i].anchor;
   }


   // create a SubPathInfo object, which holds the line array in its entireSubPath property.
   var lineSubPathArray = new Array();
   lineSubPathArray.push(new SubPathInfo());
   lineSubPathArray[0].operation = ShapeOperation.SHAPEXOR;
   lineSubPathArray[0].closed = true;
   lineSubPathArray[0].entireSubPath = lineArray;

   //create the path item, passing subpath to add method
   var myPathItem = srcDoc.pathItems.add(linename, lineSubPathArray);

   // define fillColor 
   var fillColor = new SolidColor();
   var myColour = [57, 181,74];
   fillColor.rgb.red   = myColour[0];
   fillColor.rgb.green = myColour[1];
   fillColor.rgb.blue  = myColour[2];

   //fill the path so we can see something also
   myPathItem.fillPath(fillColor,ColorBlendMode.NORMAL,100,false,0,true,true);

   // deselect path
   deselect_path();
}

// switch back to normal
app.preferences.rulerUnits = originalUnits;


// Set Display Dialogs back to normal
displayDialogs = DialogModes.ALL; // NORMAL


function deselect_path()
{
   // =======================================================
   var idslct = charIDToTypeID( "slct" );
   var desc76 = new ActionDescriptor();
   var idnull = charIDToTypeID( "null" );
   var ref63 = new ActionReference();
   var idPath = charIDToTypeID( "Path" );
   var idOrdn = charIDToTypeID( "Ordn" );
   var idTrgt = charIDToTypeID( "Trgt" );
   ref63.putEnumerated( idPath, idOrdn, idTrgt );
   desc76.putReference( idnull, ref63 );
   var idselectionModifier = stringIDToTypeID( "selectionModifier" );
   var idselectionModifierType = stringIDToTypeID( "selectionModifierType" );
   var idremoveFromSelection = stringIDToTypeID( "removeFromSelection" );
   desc76.putEnumerated( idselectionModifier, idselectionModifierType, idremoveFromSelection );
   executeAction( idslct, desc76, DialogModes.NO );

}

关于矩形太大:你把psd文件设置成什么分辨率和单位?下面的脚本将切换到像素,并将文档的分辨率设置为 72dpi

至于做笔画代替线条。嗯...你有选择。 您可以使用两点线进行笔触:

var idStrk = charIDToTypeID( "Strk" );
var desc105 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref35 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref35.putEnumerated( idPath, idOrdn, idTrgt );
desc105.putReference( idnull, ref35 );
var idUsng = charIDToTypeID( "Usng" );
var idPbTl = charIDToTypeID( "PbTl" );
desc105.putClass( idUsng, idPbTl );
executeAction( idStrk, desc105, DialogModes.NO );

但是,我认为这不是您想要的。您可以将路径变成一个形状,然后指定描边和填充颜色。但是...您至少需要 3 点才能生效。

作为建议,不要使用路径,而是从头开始创建形状 - 奇怪的是,这至少需要两个点。但我不知道如何在代码中做到这一点!

我从将 Ghoul Fool 的解决方案翻译成 Python:

中学到了两个教训
  1. 在 python 中使用 COM,可能会犯很多未被注意到的错误,除了神秘的错误消息外,还离题太远。 Thies 包括句法错误,例如 missing/redundant 括号和错误的大小写。
  2. 在 python 中使用 COM 的解决方案与 Python-Photoshop-API 的工作方式不同,反之亦然,尽管遵循库的源代码,显然发生了完全相同的事情。我并不总是能够找到双向工作的解决方案。

这里是,对于那些后来遇到这个问题的人,我得到的是一个形状层,上面有一个可以在之后改变高度的条形。调用的动作无非是从图层菜单(CS6)中记录新填充图层:

def makeBar(doc):
    app = doc.parent    
    app.preferences.rulerUnits = Units.Pixels
    
    def point(x, y):
        result               = Dispatch("Photoshop.PathPointInfo")
        result.Kind          = PointKind.CornerPoint
        result.LeftDirection = result.rightDirection = result.Anchor = (x, y)
        return result

    points = [    
              point(100, 100),
              point(200, 100),
              point(200, 110),
              point(100, 110)
              ]

    lineSubPathArray               = Dispatch("Photoshop.SubPathInfo")
    lineSubPathArray.Operation     = ShapeOperation.ShapeAdd
    lineSubPathArray.Closed        = True
    lineSubPathArray.EntireSubPath = points
    
    doc.PathItems.Add("bar-path", [lineSubPathArray])



app = Dispatch("Photoshop.Application")
doc = app.Open(self.fileName)

关于我的第二个问题:路径的角点的单位是不变的,无论他的尺子设置成什么。