如何使用CEP/JavaScript/ExtendScript在Photoshop中按坐标绘制线条
问题根源
路径首尾自动闭合是因为创建子路径时显式开启了闭合属性:
lineSubPathArray.closed = true;
该属性会强制Photoshop自动连接路径的第一个点和最后一个点,生成闭合形状。另外你当前描边参数用的是仅对闭合路径生效的内部描边,开放路径使用该参数会出现渲染异常。
修复步骤
- 关闭路径自动闭合
找到DrawShape函数中lineSubPathArray.closed = true;,修改为:
lineSubPathArray.closed = false;
- 调整描边位置适配开放路径
找到stroke_line函数中desc2613.putEnumerated( idLctn, idStrL, idInsd );,替换为以下代码,将描边位置改为开放路径支持的居中描边:
var idCntr = charIDToTypeID("Cntr"); desc2613.putEnumerated( idLctn, idStrL, idCntr );
修复后完整代码
function DrawShape(arr) { var doc = app.activeDocument; var pointCount = arr.length; // 获取文档原始高度,用于翻转Y轴坐标适配PS坐标系 var imageHeight = app.activeDocument.height.value; var pathPoints = []; for (var i = 0; i < pointCount; i++) { pathPoints[i] = new PathPointInfo; pathPoints[i].kind = PointKind.CORNERPOINT; // Y轴坐标翻转 arr[i][1] = imageHeight - arr[i][1]; pathPoints[i].anchor = arr[i]; pathPoints[i].leftDirection = pathPoints[i].anchor; pathPoints[i].rightDirection = pathPoints[i].anchor; } var lineSubPath = new SubPathInfo(); lineSubPath.closed = false; lineSubPath.operation = ShapeOperation.SHAPEADD; lineSubPath.entireSubPath = pathPoints; var myPathItem = doc.pathItems.add("myPath", [lineSubPath]); // 路径转选区 var idsetd = charIDToTypeID( "setd" ); var desc100 = new ActionDescriptor(); var idnull = charIDToTypeID( "null" ); var ref24 = new ActionReference(); var idChnl = charIDToTypeID( "Chnl" ); var idfsel = charIDToTypeID( "fsel" ); ref24.putProperty( idChnl, idfsel ); desc100.putReference( idnull, ref24 ); var idT = charIDToTypeID( "T " ); var ref25 = new ActionReference(); var idPath = charIDToTypeID( "Path" ); var idOrdn = charIDToTypeID( "Ordn" ); var idTrgt = charIDToTypeID( "Trgt" ); ref25.putEnumerated( idPath, idOrdn, idTrgt ); desc100.putReference( idT, ref25 ); var idVrsn = charIDToTypeID( "Vrsn" ); desc100.putInteger( idVrsn, 1 ); var idvectorMaskParams = stringIDToTypeID( "vectorMaskParams" ); desc100.putBoolean( idvectorMaskParams, true ); executeAction( idsetd, desc100, DialogModes.NO ); // 按参数描边 stroke_line(2, 215, 5, 5); // 取消路径选中状态 deselect_path(); // 取消选区 app.activeDocument.selection.deselect(); } function stroke_line(strokewidth, R, G, B) { var idStrk = charIDToTypeID( "Strk" ); var desc2613 = new ActionDescriptor(); var idWdth = charIDToTypeID( "Wdth" ); desc2613.putInteger( idWdth, strokewidth ); var idLctn = charIDToTypeID( "Lctn" ); var idStrL = charIDToTypeID( "StrL" ); // 开放路径使用居中描边 var idCntr = charIDToTypeID("Cntr"); desc2613.putEnumerated( idLctn, idStrL, idCntr ); var idOpct = charIDToTypeID( "Opct" ); var idPrc = charIDToTypeID( "#Prc" ); desc2613.putUnitDouble( idOpct, idPrc, 100.000000 ); var idMd = charIDToTypeID( "Md " ); var idBlnM = charIDToTypeID( "BlnM" ); var idNrml = charIDToTypeID( "Nrml" ); desc2613.putEnumerated( idMd, idBlnM, idNrml ); var idClr = charIDToTypeID( "Clr " ); var desc2614 = new ActionDescriptor(); var idRd = charIDToTypeID( "Rd " ); desc2614.putDouble( idRd, R ); var idGrn = charIDToTypeID( "Grn " ); desc2614.putDouble( idGrn, G ); var idBl = charIDToTypeID( "Bl " ); desc2614.putDouble( idBl, B ); var idRGBC = charIDToTypeID( "RGBC" ); desc2613.putObject( idClr, idRGBC, desc2614 ); executeAction( idStrk, desc2613, DialogModes.NO ); } function deselect_path() { var idDslc = charIDToTypeID( "Dslc" ); var desc154 = new ActionDescriptor(); var idNull = charIDToTypeID( "null" ); var ref127 = new ActionReference(); var idPath = charIDToTypeID( "Path" ); ref127.putClass( idPath ); desc154.putReference( idNull, ref127 ); executeAction( idDslc, desc154, DialogModes.NO ); }
优化建议
你提供的坐标序列中存在大量连续重复点,绘制前可以先做一轮去重过滤,能有效减少描边时出现的顿挫、粗细不均问题。
内容的提问来源于stack exchange,提问作者Fitspade
相关产品推荐
相关产品推荐

