// 简单 JSON.stringify 兼容 if (typeof JSON === "undefined") { JSON = {}; } var inputPath1 = '${inputPath1}'; // 载入XMP扩展支持(全局调用一次即可) if (!ExternalObject.AdobeXMPScript) { ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); } JSON.stringify = function (obj, replacer, space) { if (typeof space === "number") { space = new Array(space + 1).join(" "); } function format(value, indent) { var type = typeof value; if (value === null) return "null"; if (type === "string") return '"' + value + '"'; if (type === "number" || type === "boolean") return String(value); if (type === "object") { var isArray = (value instanceof Array); var items = []; var pad = indent + (space || ""); for (var key in value) { if (value.hasOwnProperty(key)) { var val = format(value[key], pad); if (!isArray) { val = '"' + key + '": ' + val; } items.push(val); } } if (isArray) { return "[\n" + pad + items.join(",\n" + pad) + "\n" + indent + "]"; } else { return "{\n" + pad + items.join(",\n" + pad) + "\n" + indent + "}"; } } return "null"; } return format(obj, ""); }; // 主函数 function processFile(path) { var fileRef = new File(path); if (!fileRef.exists) { // alert("PSD文件不存在: " + path); throw new Error("PSD文件不存在"); } var doc = app.open(fileRef); var result = {}; // 文档属性 result["颜色模式"] = getColorModeName(doc.mode); result["颜色深度"] = getBitsPerChannelLabel(doc.bitsPerChannel); result["图像宽度"] = doc.width.as('px') + " 像素"; result["图像高度"] = doc.height.as('px') + " 像素"; result["画布宽度"]= doc.width.as('px') + " 像素"; result["画布高度"]= doc.height.as('px') + " 像素"; result["分辨率"] = doc.resolution + " dpi"; // 图层数组 result["图层数"] = doc.artLayers.length; result["智能对象图层数"] = countSmartObjects(doc); // 图层详细信息 result["图层信息"] = []; for (var i = 0; i < doc.artLayers.length; i++) { var layer = doc.artLayers[i]; doc.activeLayer = layer; // 激活当前图层 var info = {}; info["图层名"] = layer.name; info["类型"] = getLayerKindName(layer.kind); info["可见"] = layer.visible; info["锁定"] = layer.allLocked; try { info["图层蒙版密度"] = layer.layerMaskDensity !== undefined ? layer.layerMaskDensity : null; } catch (e) {} // 文字图层特殊信息 if (layer.kind === LayerKind.TEXT) { var t = layer.textItem; try { info["文字内容"] = t.contents; } catch (e) { } try { info["字体"] = fontMap[t.font] || t.font;} // 如果找不到对应中文名,则保留英文名 catch (e) { } try { info["字号"] = t.size.toString(); }// 修正这里 catch (e) { } try { info["颜色"] = getSolidColorHex(t.color);} catch (e) { } try { info["字距"] = t.tracking;} catch (e) { } try { info["仿斜体"] = t.fauxItalic;} catch (e) { } try { info["仿粗体"] = t.fauxBold; } catch (e) { } var transformProps = getTextTransformProps(); if (transformProps) { info["变形"] = transformProps; } } // 详细读取样式(如果你需要更详细数据的话) var layerStyles = getLayerStyles(); if (layerStyles) { info["图层样式"] = layerStyles; } // 检测滤镜信息,放到info里 var filterInfo = detectFilters(layer.name); if (filterInfo) { info["滤镜信息"] = filterInfo; } result["图层信息"].push(info); } var jsonFilePath = path.replace(/\.psd$/i, ".json"); var jsonFile = new File(jsonFilePath); if (jsonFile.open("w")) { jsonFile.encoding = "UTF8"; jsonFile.write(JSON.stringify(result, null, 2)); jsonFile.close(); // alert("JSON 文件已生成: " + jsonFilePath); } else { // alert("无法打开文件进行写入: " + jsonFilePath); throw new Error("无法打开文件进行写入"); } doc.close(SaveOptions.DONOTSAVECHANGES); } // 运行两个 PSD 的处理 processFile(inputPath1); ////////////////////////////////////////////// ///////////////////////////////////////////// // 辅助函数 - 颜色模式 function getColorModeName(mode) { switch (mode) { case DocumentMode.RGB: return "RGB"; case DocumentMode.CMYK: return "CMYK"; case DocumentMode.GRAYSCALE: return "灰度"; case DocumentMode.BITMAP: return "位图"; case DocumentMode.INDEXEDCOLOR: return "索引颜色"; default: return "未知"; } } function getBitsPerChannelLabel(bits) { switch (bits) { case BitsPerChannelType.ONE: return "1 位/通道"; case BitsPerChannelType.EIGHT: return "8 位/通道"; case BitsPerChannelType.SIXTEEN: return "16 位/通道"; case BitsPerChannelType.THIRTYTWO: return "32 位/通道"; default: return "未知"; } } // 辅助函数 - 图层类型名 function getLayerKindName(kind) { switch (kind) { case LayerKind.NORMAL: return "普通图层"; case LayerKind.TEXT: return "文字图层"; case LayerKind.SMARTOBJECT: return "智能对象图层"; case LayerKind.SOLIDFILL: return "纯色填充图层"; case LayerKind.GRADIENTFILL: return "渐变填充图层"; case LayerKind.PATTERNFILL: return "图案填充图层"; case LayerKind.BRIGHTNESSCONTRAST: return "亮度/对比度调整层"; case LayerKind.LEVELS: return "色阶调整层"; case LayerKind.CURVES: return "曲线调整层"; case LayerKind.EXPOSURE: return "曝光度调整层"; case LayerKind.VIBRANCE: return "自然饱和度调整层"; case LayerKind.HUESATURATION: return "色相/饱和度调整层"; case LayerKind.COLORBALANCE: return "色彩平衡调整层"; case LayerKind.BLACKANDWHITE: return "黑白调整层"; case LayerKind.PHOTOFILTER: return "照片滤镜调整层"; case LayerKind.CHANNELMIXER: return "通道混合器调整层"; case LayerKind.COLORLOOKUP: return "颜色查找调整层"; case LayerKind.INVERSION: return "反相调整层"; case LayerKind.POSTERIZE: return "色调分离调整层"; case LayerKind.THRESHOLD: return "阈值调整层"; case LayerKind.GRADIENTMAP: return "渐变映射调整层"; case LayerKind.SELECTIVECOLOR: return "可选颜色调整层"; default: return "未知类型"; } } // 读取颜色为HEX function getSolidColorHex(color) { if (!color) return null; if (color.typename === "SolidColor") { if (color.rgb) { var r = Math.round(color.rgb.red); var g = Math.round(color.rgb.green); var b = Math.round(color.rgb.blue); return "#" + toHex(r) + toHex(g) + toHex(b); } } return null; } function toHex(c) { var h = c.toString(16); return h.length == 1 ? "0" + h : h; } // 统计智能对象图层数量 function countSmartObjects(doc) { var count = 0; for (var i = 0; i < doc.artLayers.length; i++) { if (doc.artLayers[i].kind === LayerKind.SMARTOBJECT) { count++; } } return count; } // 读取文字图层的变形属性 function getTextTransformProps() { try { var ref = new ActionReference(); ref.putEnumerated(stringIDToTypeID("layer"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); var desc = executeActionGet(ref); if (desc.hasKey(stringIDToTypeID("textKey"))) { var textDesc = desc.getObjectValue(stringIDToTypeID("textKey")); if (textDesc.hasKey(stringIDToTypeID("transform"))) { var transformDesc = textDesc.getObjectValue(stringIDToTypeID("transform")); var horizontal = transformDesc.getDouble(stringIDToTypeID("horizontalShear")); var vertical = transformDesc.getDouble(stringIDToTypeID("verticalShear")); var scaleX = transformDesc.getDouble(stringIDToTypeID("horizontalScale")); var scaleY = transformDesc.getDouble(stringIDToTypeID("verticalScale")); return { "水平扭曲": horizontal.toFixed(2) + "%", "垂直扭曲": vertical.toFixed(2) + "%", "水平缩放": scaleX.toFixed(2) + "%", "垂直缩放": scaleY.toFixed(2) + "%" }; } } } catch (e) { return null; } return null; } function getLayerStyles() { try { var ref = new ActionReference(); ref.putEnumerated(stringIDToTypeID("layer"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); var desc = executeActionGet(ref); if (!desc.hasKey(stringIDToTypeID("layerEffects"))) { $.writeln("图层无layerEffects"); return null; } var effects = desc.getObjectValue(stringIDToTypeID("layerEffects")); var styles = {}; // ============ 描边 =============== if (effects.hasKey(stringIDToTypeID("frameFX"))) { var frameFX = effects.getObjectValue(stringIDToTypeID("frameFX")); styles["描边_启用"] = frameFX.getBoolean(stringIDToTypeID("enabled")); if (styles["描边_启用"]) { if (frameFX.hasKey(stringIDToTypeID("size"))) { styles["描边_大小"] = frameFX.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; } if (frameFX.hasKey(stringIDToTypeID("color"))) { var colorDesc = frameFX.getObjectValue(stringIDToTypeID("color")); styles["描边_颜色"] = colorDescToHex(colorDesc); } if (frameFX.hasKey(stringIDToTypeID("position"))) { var pos = frameFX.getEnumerationValue(stringIDToTypeID("position")); styles["描边_位置"] = getStrokePositionName(pos); } if (frameFX.hasKey(stringIDToTypeID("opacity"))) { styles["描边_不透明度"] = Math.round(frameFX.getUnitDoubleValue(stringIDToTypeID("opacity"))) + "%"; } if (frameFX.hasKey(stringIDToTypeID("blendMode"))) { var blendMode = frameFX.getEnumerationValue(stringIDToTypeID("blendMode")); styles["描边_混合模式"] = getBlendModeName(blendMode); } } } // ============ 内发光 =============== if (effects.hasKey(stringIDToTypeID("innerGlow"))) { var innerGlow = effects.getObjectValue(stringIDToTypeID("innerGlow")); styles["内发光_启用"] = innerGlow.getBoolean(stringIDToTypeID("enabled")); if (styles["内发光_启用"]) { if (innerGlow.hasKey(stringIDToTypeID("opacity"))) { styles["内发光_不透明度"] = Math.round(innerGlow.getUnitDoubleValue(stringIDToTypeID("opacity")) ) + "%"; } if (innerGlow.hasKey(stringIDToTypeID("color"))) { styles["内发光_颜色"] = colorDescToHex(innerGlow.getObjectValue(stringIDToTypeID("color"))); } if (innerGlow.hasKey(stringIDToTypeID("glowTechnique"))) { var tech = innerGlow.getEnumerationValue(stringIDToTypeID("glowTechnique")); styles["内发光_技巧"] = getInnerGlowTechniqueName(tech); } if (innerGlow.hasKey(stringIDToTypeID("source"))) { var source = innerGlow.getEnumerationValue(stringIDToTypeID("source")); styles["内发光_来源"] = getInnerGlowSourceName(source); } if (innerGlow.hasKey(stringIDToTypeID("chokeMatte"))) { styles["内发光_阻塞"] = innerGlow.getUnitDoubleValue(stringIDToTypeID("chokeMatte")) + " 像素"; } if (innerGlow.hasKey(stringIDToTypeID("blur"))) { styles["内发光_模糊"] = innerGlow.getUnitDoubleValue(stringIDToTypeID("blur")) + " 像素"; } } } // ============ 斜面和浮雕 =============== if (effects.hasKey(stringIDToTypeID("bevelEmboss"))) { var bevel = effects.getObjectValue(stringIDToTypeID("bevelEmboss")); styles["斜面和浮雕_启用"] = bevel.getBoolean(stringIDToTypeID("enabled")); if (styles["斜面和浮雕_启用"]) { if (bevel.hasKey(stringIDToTypeID("style"))) { styles["斜面和浮雕_样式"] = getBevelStyleName(bevel.getEnumerationValue(stringIDToTypeID("style"))); } if (bevel.hasKey(stringIDToTypeID("technique"))) { styles["斜面和浮雕_方法"] = getBevelTechniqueName(bevel.getEnumerationValue(stringIDToTypeID("technique"))); } if (bevel.hasKey(stringIDToTypeID("depth"))) { styles["斜面和浮雕_深度"] = bevel.getInteger(stringIDToTypeID("depth")) + "%"; } if (bevel.hasKey(stringIDToTypeID("direction"))) { styles["斜面和浮雕_方向"] = getBevelDirectionName(bevel.getEnumerationValue(stringIDToTypeID("direction"))); } if (bevel.hasKey(stringIDToTypeID("size"))) { styles["斜面和浮雕_大小"] = bevel.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; } if (bevel.hasKey(stringIDToTypeID("soften"))) { styles["斜面和浮雕_软化"] = bevel.getUnitDoubleValue(stringIDToTypeID("soften")) + " 像素"; } if (bevel.hasKey(stringIDToTypeID("useGlobalAngle"))) { styles["斜面和浮雕_全局光"] = bevel.getBoolean(stringIDToTypeID("useGlobalAngle")); } if (bevel.hasKey(stringIDToTypeID("angle"))) { styles["斜面和浮雕_角度"] = bevel.getDouble(stringIDToTypeID("angle")).toFixed(1) + "°"; } if (bevel.hasKey(stringIDToTypeID("highlightMode"))) { var highlight = bevel.getObjectValue(stringIDToTypeID("highlightMode")); if (highlight.hasKey(stringIDToTypeID("mode"))) { styles["斜面和浮雕_高光模式"] = getBlendModeName(highlight.getEnumerationValue(stringIDToTypeID("mode"))); } if (highlight.hasKey(stringIDToTypeID("color"))) { styles["斜面和浮雕_高光颜色"] = colorDescToHex(highlight.getObjectValue(stringIDToTypeID("color"))); } } if (bevel.hasKey(stringIDToTypeID("shadowMode"))) { var shadow = bevel.getObjectValue(stringIDToTypeID("shadowMode")); if (shadow.hasKey(stringIDToTypeID("mode"))) { styles["斜面和浮雕_阴影模式"] = getBlendModeName(shadow.getEnumerationValue(stringIDToTypeID("mode"))); } if (shadow.hasKey(stringIDToTypeID("color"))) { styles["斜面和浮雕_阴影颜色"] = colorDescToHex(shadow.getObjectValue(stringIDToTypeID("color"))); } } } } // ============ 光泽 =============== if (effects.hasKey(stringIDToTypeID("glossContour"))) { styles["光泽_启用"] = true; // 简化处理 var gloss = effects.getObjectValue(stringIDToTypeID("glossContour")); if (gloss.hasKey(stringIDToTypeID("range"))) { styles["光泽_范围"] = (gloss.getDouble(stringIDToTypeID("range")) * 100).toFixed(1) + "%"; } if (gloss.hasKey(stringIDToTypeID("highlightSize"))) { styles["光泽_高光大小"] = gloss.getUnitDoubleValue(stringIDToTypeID("highlightSize")) + " 像素"; } } // ============ 外发光 =============== if (effects.hasKey(stringIDToTypeID("outerGlow"))) { var outerGlow = effects.getObjectValue(stringIDToTypeID("outerGlow")); styles["外发光_启用"] = outerGlow.getBoolean(stringIDToTypeID("enabled")); if (styles["外发光_启用"]) { if (outerGlow.hasKey(stringIDToTypeID("opacity"))) { styles["外发光_不透明度"] = Math.round(outerGlow.getUnitDoubleValue(stringIDToTypeID("opacity")) ) + "%"; } if (outerGlow.hasKey(stringIDToTypeID("color"))) { styles["外发光_颜色"] = colorDescToHex(outerGlow.getObjectValue(stringIDToTypeID("color"))); } if (outerGlow.hasKey(stringIDToTypeID("technique"))) { styles["外发光_图素方法"] = getOuterGlowTechniqueName(outerGlow.getEnumerationValue(stringIDToTypeID("technique"))); } if (outerGlow.hasKey(stringIDToTypeID("size"))) { styles["外发光_大小"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; } if (outerGlow.hasKey(stringIDToTypeID("spread"))) { styles["外发光_扩展"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("spread")) + " 像素"; } if (outerGlow.hasKey(stringIDToTypeID("contour"))) { var contour = outerGlow.getObjectValue(stringIDToTypeID("contour")); styles["外发光_等高线"] = getContourName(contour.getEnumerationValue(stringIDToTypeID("name"))); } } } return hasOwnProperties(styles) ? styles : null; } catch (e) { $.writeln("读取图层样式异常: " + e.message); return null; } } // 辅助函数:描边位置 function getStrokePositionName(value) { switch (value) { case stringIDToTypeID("inside"): return "内侧"; case stringIDToTypeID("center"): return "居中"; case stringIDToTypeID("outside"): return "外侧"; default: return "未知"; } } // 斜面和浮雕 样式名称 function getBevelStyleName(value) { switch (value) { case stringIDToTypeID("outerBevel"): return "外斜面"; case stringIDToTypeID("innerBevel"): return "内斜面"; case stringIDToTypeID("emboss"): return "浮雕"; case stringIDToTypeID("pillowEmboss"): return "枕头状浮雕"; default: return "未知"; } } // 斜面和浮雕 方法 function getBevelTechniqueName(value) { switch (value) { case stringIDToTypeID("smooth"): return "平滑"; case stringIDToTypeID("chiselHard"): return "雕刻清晰"; case stringIDToTypeID("chiselSoft"): return "雕刻柔和"; default: return "未知"; } } // 斜面和浮雕 方向 function getBevelDirectionName(value) { switch (value) { case stringIDToTypeID("up"): return "上"; case stringIDToTypeID("down"): return "下"; default: return "未知"; } } // 图层混合模式 function getBlendModeName(value) { switch (value) { case stringIDToTypeID("normal"): return "正常"; case stringIDToTypeID("multiply"): return "正片叠底"; case stringIDToTypeID("screen"): return "滤色"; case stringIDToTypeID("overlay"): return "叠加"; case stringIDToTypeID("softLight"): return "柔光"; case stringIDToTypeID("hardLight"): return "强光"; case stringIDToTypeID("difference"): return "差值"; case stringIDToTypeID("colorBurn"): return "颜色加深"; case stringIDToTypeID("colorDodge"): return "颜色减淡"; case stringIDToTypeID("lighten"): return "变亮"; case stringIDToTypeID("darken"): return "变暗"; default: return "其他"; } } // 外发光 图素方法 function getOuterGlowTechniqueName(value) { switch (value) { case stringIDToTypeID("precise"): return "精确"; case stringIDToTypeID("softer"): return "柔和"; default: return "未知"; } } // 等高线名称(外发光等) function getContourName(value) { switch (value) { case stringIDToTypeID("linear"): return "线性"; case stringIDToTypeID("ring"): return "环形"; case stringIDToTypeID("cone"): return "锥形"; case stringIDToTypeID("cove"): return "凹形"; case stringIDToTypeID("stairs"): return "阶梯"; case stringIDToTypeID("custom"): return "自定义"; case stringIDToTypeID("zigZag"): return "锯齿1"; case stringIDToTypeID("roundedSteps"): return "圆角阶梯"; default: return "未知"; } } function colorDescToHex(colorDesc) { try { var red = Math.round(colorDesc.getDouble(stringIDToTypeID('red'))); var green = Math.round(colorDesc.getDouble(stringIDToTypeID('green'))); var blue = Math.round(colorDesc.getDouble(stringIDToTypeID('blue'))); return rgbToHex(red, green, blue); } catch (e) { return null; } } function getInnerGlowTechniqueName(value) { switch(value) { case stringIDToTypeID("precise"): return "精确"; case stringIDToTypeID("softer"): return "柔和"; default: return "未知"; } } function getInnerGlowSourceName(value) { switch(value) { case stringIDToTypeID("center"): return "中心"; case stringIDToTypeID("edge"): return "边缘"; default: return "未知"; } } function rgbToHex(r, g, b) { return "#" + [r, g, b].map(function(x) { var hex = x.toString(16); return hex.length === 1 ? "0" + hex : hex; }).join(''); } // 滤镜检测示例(只检测图层名包含的关键词) // 修改后的detectFilters函数,优先用XMP元数据读取镜头光晕参数 function detectFilters(layerName) { var filters = {}; if (!layerName || typeof layerName !== "string") { return null; } var name = layerName.toLowerCase(); // 先尝试读取XMP中镜头光晕参数 var lensFlareMeta = readHistoryFromXMP(); if (lensFlareMeta) { return lensFlareMeta; // 直接返回读取的元数据 } // else { // // 没读到元数据,返回默认提示 // filters["滤镜类型"] = "镜头光晕"; // filters["亮度"] = "⚠️ 无法读取,建议人工确认"; // filters["镜头类型"] = "⚠️ 无法读取,建议人工确认"; // return filters; // } } // 结合你的读取函数用法举例 function readHistoryFromXMP() { try { if (typeof ExternalObject.AdobeXMPScript === "undefined") { ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript"); } var xmp = new XMPMeta(app.activeDocument.xmpMetadata.rawData); var nsMM = "http://ns.adobe.com/xap/1.0/mm/"; var nsEvt = "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"; XMPMeta.registerNamespace(nsMM, "xmpMM"); XMPMeta.registerNamespace(nsEvt, "stEvt"); var count = xmp.countArrayItems(nsMM, "History"); if (count === 0) { $.writeln("没有找到历史记录"); return null; } for (var i = 1; i <= count; i++) { var itemXMP = xmp.getArrayItem(nsMM, "History", i); var historyLine = itemXMP.toString(); $.writeln("历史记录第" + i + "条: " + historyLine); if (historyLine.indexOf("镜头光晕") !== -1 || historyLine.toLowerCase().indexOf("lens flare") !== -1) { var brightnessMatch = historyLine.match(/亮度[::]?\s*(\d+%?)/); var typeMatch = historyLine.match(/类型[::]?\s*([^\s]+)/); return { "历史":historyLine, "滤镜类型": "镜头光晕", "亮度": brightnessMatch ? brightnessMatch[1] : "未知", "镜头类型": typeMatch ? typeMatch[1] : "未知" }; } } } catch (e) { return { "读取XMP历史记录失败:": e.message }; } } var fontMap = { "SimSun": "宋体", "SimHei": "黑体", "FangSong_GB2312": "仿宋", "KaiTi_GB2312": "楷体", "MicrosoftYaHei": "微软雅黑", "MicrosoftJhengHei": "微软正黑体", "NSimSun": "新宋体", "PMingLiU": "新细明体", "MingLiU": "细明体", "DFKai-SB": "标楷体", "STKaiti": "华文楷体", "STSong": "华文宋体", "STHeiti": "华文黑体", "STFangsong": "华文仿宋", "STXihei": "华文细黑", "STZhongsong": "华文中宋", "STXinwei": "华文新魏", "STLiti": "华文隶书", "STHupo": "华文琥珀", "STCaiyun": "华文彩云", "STXingkai": "华文行楷", "STHupo": "华文琥珀", "STFangsong": "华文仿宋", "Arial": "Arial(英文字体)", "TimesNewRomanPSMT": "Times New Roman", "CourierNewPSMT": "Courier New", "Georgia": "Georgia", "Tahoma": "Tahoma", "Verdana": "Verdana" }; // 判断对象是否含有自有属性(兼容无Object.keys的环境) function hasOwnProperties(obj) { for (var key in obj) { if (obj.hasOwnProperty(key)) { return true; } } return false; }