diff --git a/checkPSD.jsx b/checkPSD.jsx index 3600b08..1c2331a 100644 --- a/checkPSD.jsx +++ b/checkPSD.jsx @@ -1,12 +1,10 @@ - // 简单 JSON.stringify 兼容 if (typeof JSON === "undefined") { JSON = {}; } var inputPath1 = '${inputPath1}'; - // 载入XMP扩展支持(全局调用一次即可) if (!ExternalObject.AdobeXMPScript) { ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); @@ -47,51 +45,32 @@ JSON.stringify = function (obj, replacer, space) { -// 主函数 -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; // 激活当前图层 - +// 递归遍历所有图层(包括图层组) +function processLayers(layers, resultArray) { + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + app.activeDocument.activeLayer = layer; var info = {}; + + // 先保存锁定状态 + var wasLocked = layer.allLocked; + if (wasLocked) { + try { + layer.allLocked = false; // 临时解锁 + } catch (e) { + // 有些锁可能无法解除,忽略异常 + } + } 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.visible === true) { + info["可见"] = true; + } + if (layer.allLocked === true) { + info["锁定"] = true; + } // 文字图层特殊信息 if (layer.kind === LayerKind.TEXT) { @@ -102,62 +81,253 @@ function processFile(path) { } try { - info["字体"] = fontMap[t.font] || t.font;} // 如果找不到对应中文名,则保留英文名 + var font = t.font; + 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": "华文行楷", + "Arial": "Arial(英文字体)", + "TimesNewRomanPSMT": "Times New Roman", + "CourierNewPSMT": "Courier New", + "Georgia": "Georgia", + "Tahoma": "Tahoma", + "Verdana": "Verdana" + }; + + if (fontMap.hasOwnProperty(font)) { + info["字体"] = fontMap[font]; + } else { + info["字体"] = font; + } + } catch (e) { + info["字体"] = "未知"; + } + + try { + info["字号"] = t.size.toString(); }// 修正这里 + catch (e) { + } + + try { + info["颜色"] = getSolidColorHex(t.color);} catch (e) { - } - try { - info["字号"] = t.size.toString(); }// 修正这里 - catch (e) { - } - - try { - info["颜色"] = getSolidColorHex(t.color);} - catch (e) { - - } - try { + } + try { info["字距"] = t.tracking;} - catch (e) { - - } - try { - info["仿斜体"] = t.fauxItalic;} - catch (e) { - - } - try { - info["仿粗体"] = t.fauxBold; - } catch (e) { + catch (e) { + } + try { + if ('fauxItalic' in t && t.fauxItalic === true) { + info["仿斜体"] = true; } + } catch (e) {} - var transformProps = getTextTransformProps(); - if (transformProps) { + try { + if ('fauxBold' in t && t.fauxBold === true) { + info["仿粗体"] = true; + } + } catch (e) {} + + var transformProps = getWarpTextProps(); + if ( + transformProps && + typeof transformProps === "object" && + (function(obj) { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + return true; // 有至少一个属性,不为空 + } + } + return false; // 没有属性,为空 + })(transformProps) + ) { info["变形"] = transformProps; } + } - - // 详细读取样式(如果你需要更详细数据的话) - var layerStyles = getLayerStyles(); - if (layerStyles) { - info["图层样式"] = layerStyles; + // 读取图层样式 + var styles = getLayerStyles(layer); + if (styles) { + info["图层样式"] = styles; } - // 检测滤镜信息,放到info里 + // 检测滤镜信息 var filterInfo = detectFilters(layer.name); if (filterInfo) { info["滤镜信息"] = filterInfo; } - result["图层信息"].push(info); + + // 选中当前图层为智能对象后 + var soLayer = app.activeDocument.activeLayer; + + // 确保它是智能对象 + // if (soLayer.kind == LayerKind.SMARTOBJECT) { + // // 打开智能对象 + // var openedDoc = soLayer.smartObject.open(); + + // // 现在 activeDocument 是智能对象内容,可以像普通文档一样读取图层 + // var internalLayer = openedDoc.artLayers[0]; // 你可以遍历所有图层 + // var styles = getLayerStyles(internalLayer); + // alert(JSON.stringify(styles)); + + // // 读取完后关闭文档(不保存) + // openedDoc.close(SaveOptions.DONOTSAVECHANGES); + // } + + + + // 如果是图层组,递归遍历组内图层 + if (layer.typename === "LayerSet") { + info["子图层"] = []; + processLayers(layer.layers, info["子图层"]); + } + + resultArray.push(info); + + // 还原锁定状态 + if (wasLocked) { + try { + layer.allLocked = true; + } catch (e) {} + } + } +} +function unlockLayer(layer) { + // 如果图层被完全锁定 + if (layer.allLocked) { + layer.allLocked = false; + } + // 如果是背景图层(通常无法直接操作) + if (layer.isBackgroundLayer) { + // 将背景图层转换为普通图层 + layer.name = "解锁背景图层"; + layer.isBackgroundLayer = false; + } + + // 分别检查并解锁其他锁定项 + if (layer.pixelsLocked) layer.pixelsLocked = false; + if (layer.positionLocked) layer.positionLocked = false; + if (layer.transparentPixelsLocked) layer.transparentPixelsLocked = false; +} + + +function openSmartObjectDocument(layer) { + try { + app.activeDocument.activeLayer = layer; // 先激活图层 + var idplacedLayerEditContents = stringIDToTypeID("placedLayerEditContents"); + var desc = new ActionDescriptor(); + var ref = new ActionReference(); + ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); + desc.putReference(charIDToTypeID("null"), ref); + executeAction(idplacedLayerEditContents, desc, DialogModes.NO); + + return app.activeDocument; // 返回智能对象内部文档 + } catch (e) { + $.writeln("打开智能对象内部文档失败:" + e.message); + return null; + } +} + +function openSmartObjectDocumentEvenIfLocked(layer) { + var wasLocked = layer.allLocked; + try { + if (wasLocked) { + try { layer.allLocked = false; } catch(e) {} + try { layer.pixelsLocked = false; } catch(e) {} + try { layer.positionLocked = false; } catch(e) {} + try { layer.transparentPixelsLocked = false; } catch(e) {} + } + + var idPlacedLayerEditContents = stringIDToTypeID("placedLayerEditContents"); + var desc = new ActionDescriptor(); + var ref = new ActionReference(); + ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); + desc.putReference(charIDToTypeID("null"), ref); + executeAction(idPlacedLayerEditContents, desc, DialogModes.NO); + + return app.activeDocument; + } catch (e) { + // alert("打开智能对象内部文档失败:" + e.message); + return null; + } finally { + if (wasLocked) { + try { layer.allLocked = true; } catch(e) {} + } + } +} + + + +function getSmartObjectType(layer) { + try { + var ref = new ActionReference(); + ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); + var desc = executeActionGet(ref); + if (desc.hasKey(stringIDToTypeID("smartObject"))) { + var smObj = desc.getObjectValue(stringIDToTypeID("smartObject")); + if (smObj.hasKey(stringIDToTypeID("linked"))) { + var isLinked = smObj.getBoolean(stringIDToTypeID("linked")); + return isLinked ? "链接智能对象" : "嵌入智能对象"; + } + } + } catch (e) { + return "未知类型"; + } + return "未知类型"; +} + +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 = {}; - var jsonFilePath = path.replace(/\.psd$/i, ".json"); + 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["图层信息"] = []; + processLayers(doc.layers, result["图层信息"]); + + // 获取智能对象图层数(递归计算) + result["智能对象图层数"] = countSmartObjectsRecursive(doc.layers); + + // 写入 JSON 文件 + var baseName = fileRef.name.replace(/\.psd$/i, ""); + var jsonFilePath = fileRef.path + "/" + baseName + ".json"; var jsonFile = new File(jsonFilePath); if (jsonFile.open("w")) { @@ -166,15 +336,25 @@ function processFile(path) { jsonFile.close(); // alert("JSON 文件已生成: " + jsonFilePath); } else { - // alert("无法打开文件进行写入: " + jsonFilePath); - throw new Error("无法打开文件进行写入"); + // alert("无法打开文件进行写入"); } - doc.close(SaveOptions.DONOTSAVECHANGES); - - } + +// 递归计算智能对象图层数 +function countSmartObjectsRecursive(layers) { + var count = 0; + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + if (layer.kind === LayerKind.SMARTOBJECT) count++; + if (layer.typename === "LayerSet") { + count += countSmartObjectsRecursive(layer.layers); + } + } + return count; +} + // 运行两个 PSD 的处理 processFile(inputPath1); @@ -263,41 +443,93 @@ function countSmartObjects(doc) { } // 读取文字图层的变形属性 -function getTextTransformProps() { +// 读取文字图层的变形属性(分开返回属性并汉化样式) +function getWarpTextProps() { try { var ref = new ActionReference(); - ref.putEnumerated(stringIDToTypeID("layer"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); + ref.putEnumerated(charIDToTypeID("Lyr "), 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) + "%" + + if (textDesc.hasKey(stringIDToTypeID("warp"))) { + var warpDesc = textDesc.getObjectValue(stringIDToTypeID("warp")); + + // 获取英文样式 + var warpStyleEn = warpDesc.hasKey(stringIDToTypeID("warpStyle")) + ? typeIDToStringID(warpDesc.getEnumerationValue(stringIDToTypeID("warpStyle"))) + : "none"; + + // 样式汉化映射 + var warpStyleMap = { + "warpNone": "无", + "warpArc": "弧形", + "warpArcLower": "下弧形", + "warpArcUpper": "上弧形", + "warpArch": "拱形", + "warpBulge": "凸出", + "warpShellLower": "下壳形", + "warpShellUpper": "上壳形", + "warpFlag": "旗帜", + "warpWave": "波浪", + "warpFish": "鱼形", + "warpRise": "上升", + "warpFisheye": "鱼眼", + "warpInflate": "膨胀", + "warpSqueeze": "挤压", + "warpTwist": "扭曲" }; + + // 汉化样式 + var warpStyleCn = warpStyleMap[warpStyleEn] || warpStyleEn; + + var warpHorizontal = warpDesc.hasKey(stringIDToTypeID("warpValue")) + ? warpDesc.getDouble(stringIDToTypeID("warpValue")) + "%" + : "0%"; + + var warpVertical = warpDesc.hasKey(stringIDToTypeID("warpPerspective")) + ? warpDesc.getDouble(stringIDToTypeID("warpPerspective")) + "%" + : "0%"; + + var warpEnabled = warpDesc.hasKey(stringIDToTypeID("warpFlag")) + ? warpDesc.getBoolean(stringIDToTypeID("warpFlag")) + : false; + + var result = {}; + + if (warpStyleCn !== "无") { + result["样式"] = warpStyleCn; + result["水平扭曲"] = warpHorizontal; + result["垂直扭曲"] = warpVertical; + } + + if (warpEnabled === true) { + result["是否变形"] = true; + } + + return result; + } else { + return { "提示": "该文字图层没有使用变形文字" }; } } } catch (e) { - return null; + // alert("读取变形文字属性时出错: " + e.message); } + return null; } -function getLayerStyles() { + + +function getLayerStyles(layer) { try { var ref = new ActionReference(); - ref.putEnumerated(stringIDToTypeID("layer"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); + ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); var desc = executeActionGet(ref); if (!desc.hasKey(stringIDToTypeID("layerEffects"))) { - $.writeln("图层无layerEffects"); + $.writeln("图层无 layerEffects:" + layer.name); return null; } @@ -307,8 +539,13 @@ function getLayerStyles() { // ============ 描边 =============== if (effects.hasKey(stringIDToTypeID("frameFX"))) { var frameFX = effects.getObjectValue(stringIDToTypeID("frameFX")); + var keys = []; + for (var i = 0; i < frameFX.count; i++) { + keys.push(i + ": " + typeIDToStringID(frameFX.getKey(i))); + } + var enabled = frameFX.getBoolean(stringIDToTypeID("enabled")); styles["描边_启用"] = frameFX.getBoolean(stringIDToTypeID("enabled")); - if (styles["描边_启用"]) { + if (enabled) { if (frameFX.hasKey(stringIDToTypeID("size"))) { styles["描边_大小"] = frameFX.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; } @@ -316,15 +553,19 @@ function getLayerStyles() { 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("style"))) { + var posEnum = frameFX.getEnumerationValue(stringIDToTypeID("style")); + var posStringID = typeIDToStringID(posEnum); + styles["描边_位置"] = getStrokePositionName(posStringID); + } else { + styles["描边_位置"] = "未知"; } + if (frameFX.hasKey(stringIDToTypeID("opacity"))) { styles["描边_不透明度"] = Math.round(frameFX.getUnitDoubleValue(stringIDToTypeID("opacity"))) + "%"; } - if (frameFX.hasKey(stringIDToTypeID("blendMode"))) { - var blendMode = frameFX.getEnumerationValue(stringIDToTypeID("blendMode")); + if (frameFX.hasKey(stringIDToTypeID("mode"))) { + var blendMode = frameFX.getEnumerationValue(stringIDToTypeID("mode")); styles["描边_混合模式"] = getBlendModeName(blendMode); } } @@ -333,91 +574,79 @@ function getLayerStyles() { // ============ 内发光 =============== if (effects.hasKey(stringIDToTypeID("innerGlow"))) { var innerGlow = effects.getObjectValue(stringIDToTypeID("innerGlow")); + // var keys = []; + // for (var i = 0; i < innerGlow.count; i++) { + // keys.push(i + ": " + typeIDToStringID(innerGlow.getKey(i))); + // } styles["内发光_启用"] = innerGlow.getBoolean(stringIDToTypeID("enabled")); if (styles["内发光_启用"]) { if (innerGlow.hasKey(stringIDToTypeID("opacity"))) { styles["内发光_不透明度"] = Math.round(innerGlow.getUnitDoubleValue(stringIDToTypeID("opacity")) ) + "%"; } + + if (innerGlow.hasKey(stringIDToTypeID("mode"))) { + var modeID = innerGlow.getEnumerationValue(stringIDToTypeID("mode")); + styles["内发光_混合模式"] = getBlendModeName(modeID); + } + + if (innerGlow.hasKey(stringIDToTypeID("blur"))) { + styles["内发光_大小"] = innerGlow.getUnitDoubleValue(stringIDToTypeID("blur")) + " 像素"; + } 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("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 (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) + "°"; + styles["斜面_启用"] = bevel.getBoolean(stringIDToTypeID("enabled")); + if (styles["斜面_启用"]) { + styles["斜面_样式"] = typeIDToStringID(bevel.getEnumerationValue(stringIDToTypeID("style"))); + styles["斜面_方法"] = typeIDToStringID(bevel.getEnumerationValue(stringIDToTypeID("technique"))); + styles["斜面_深度"] = bevel.getDouble(stringIDToTypeID("strength")) + "%"; + styles["斜面_方向"] = typeIDToStringID(bevel.getEnumerationValue(stringIDToTypeID("direction"))); + styles["斜面_大小"] = bevel.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; + styles["斜面_软化"] = bevel.getUnitDoubleValue(stringIDToTypeID("soften")) + " 像素"; + styles["斜面_使用全局光"] = bevel.getBoolean(stringIDToTypeID("useGlobalAngle")); + styles["斜面_角度"] = bevel.getInteger(stringIDToTypeID("localLightingAngle")) + "°"; + + if (bevel.hasKey(stringIDToTypeID("highlightColor"))) { + var color = bevel.getObjectValue(stringIDToTypeID("highlightColor")); + styles["斜面_高光颜色"] = colorToHex(color); } 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"))); - } + var mode = bevel.getEnumerationValue(stringIDToTypeID("highlightMode")); + styles["斜面_高光模式"] = typeIDToStringID(mode); } } } - // ============ 光泽 =============== - 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")) + " 像素"; + // ========= 光泽(Satin) ========= + if (effects.hasKey(stringIDToTypeID("satin"))) { + var satin = effects.getObjectValue(stringIDToTypeID("satin")); + styles["光泽_启用"] = satin.getBoolean(stringIDToTypeID("enabled")); + if (styles["光泽_启用"]) { + styles["光泽_混合模式"] = typeIDToStringID(satin.getEnumerationValue(stringIDToTypeID("mode"))); + styles["光泽_不透明度"] = satin.getInteger(stringIDToTypeID("opacity")) + "%"; + styles["光泽_角度"] = satin.getInteger(stringIDToTypeID("localLightingAngle")) + "°"; + styles["光泽_距离"] = satin.getUnitDoubleValue(stringIDToTypeID("distance")) + " 像素"; + styles["光泽_大小"] = satin.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; } } @@ -425,6 +654,14 @@ function getLayerStyles() { if (effects.hasKey(stringIDToTypeID("outerGlow"))) { var outerGlow = effects.getObjectValue(stringIDToTypeID("outerGlow")); styles["外发光_启用"] = outerGlow.getBoolean(stringIDToTypeID("enabled")); + // 遍历输出所有 key 名称,方便调试 + // var keys = []; + // for (var i = 0; i < outerGlow.count; i++) { + // var key = outerGlow.getKey(i); + // var keyName = typeIDToStringID(key); + // keys.push(keyName); + // } + if (styles["外发光_启用"]) { if (outerGlow.hasKey(stringIDToTypeID("opacity"))) { styles["外发光_不透明度"] = Math.round(outerGlow.getUnitDoubleValue(stringIDToTypeID("opacity")) ) + "%"; @@ -432,26 +669,48 @@ function getLayerStyles() { 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("glowTechnique"))) { + var techniqueEnum = outerGlow.getEnumerationValue(stringIDToTypeID("glowTechnique")); + var techniqueStr = typeIDToStringID(techniqueEnum); + + styles["外发光_图素方法"] = getOuterGlowTechniqueName(techniqueStr); // 例如返回"精确" } - if (outerGlow.hasKey(stringIDToTypeID("size"))) { - styles["外发光_大小"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素"; + + if (outerGlow.hasKey(stringIDToTypeID("blur"))) { + styles["外发光_大小"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("blur")) + " 像素"; } - if (outerGlow.hasKey(stringIDToTypeID("spread"))) { - styles["外发光_扩展"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("spread")) + " 像素"; + if (outerGlow.hasKey(stringIDToTypeID("chokeMatte"))) { + styles["外发光_阻塞"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("chokeMatte")) + " 像素"; } - if (outerGlow.hasKey(stringIDToTypeID("contour"))) { - var contour = outerGlow.getObjectValue(stringIDToTypeID("contour")); - styles["外发光_等高线"] = getContourName(contour.getEnumerationValue(stringIDToTypeID("name"))); + try{ + if (outerGlow.hasKey(stringIDToTypeID("transferSpec"))) { + var transferSpec = outerGlow.getObjectValue(stringIDToTypeID("transferSpec")); // 先获取对象 + var nameID = stringIDToTypeID("name"); + if (transferSpec.hasKey(nameID)) { + styles["外发光_等高线"] = transferSpec.getString(nameID); + } + } + + } catch (e) { + // alert("外发光_等高线: " + e.message); + return null; } + + + + if (outerGlow.hasKey(stringIDToTypeID("mode"))) { + var blendMode = outerGlow.getEnumerationValue(stringIDToTypeID("mode")); + styles["外发光_混合模式"] = getBlendModeName(blendMode); + } + } } + return hasOwnProperties(styles) ? styles : null; } catch (e) { - $.writeln("读取图层样式异常: " + e.message); + // alert("读取图层样式异常: " + e.message); return null; } } @@ -460,15 +719,16 @@ function getLayerStyles() { // 辅助函数:描边位置 -function getStrokePositionName(value) { - switch (value) { - case stringIDToTypeID("inside"): return "内侧"; - case stringIDToTypeID("center"): return "居中"; - case stringIDToTypeID("outside"): return "外侧"; +function getStrokePositionName(posStringID) { + switch(posStringID) { + case "outsetFrame": return "外侧"; + case "insideFrame": return "内侧"; + case "centeredFrame": return "居中"; default: return "未知"; } } + // 斜面和浮雕 样式名称 function getBevelStyleName(value) { switch (value) { @@ -496,6 +756,7 @@ function getBevelDirectionName(value) { default: return "未知"; } } + // 图层混合模式 function getBlendModeName(value) { switch (value) { @@ -504,23 +765,33 @@ function getBlendModeName(value) { case stringIDToTypeID("screen"): return "滤色"; case stringIDToTypeID("overlay"): return "叠加"; case stringIDToTypeID("softLight"): return "柔光"; + case stringIDToTypeID("linearLight"): return "亮光"; case stringIDToTypeID("hardLight"): return "强光"; + case stringIDToTypeID("vividLight"): return "亮光"; + case stringIDToTypeID("pinLight"): return "点光"; case stringIDToTypeID("difference"): return "差值"; case stringIDToTypeID("colorBurn"): return "颜色加深"; case stringIDToTypeID("colorDodge"): return "颜色减淡"; case stringIDToTypeID("lighten"): return "变亮"; case stringIDToTypeID("darken"): return "变暗"; + case stringIDToTypeID("dissolve"): return "溶解"; + case stringIDToTypeID("hue"): return "色相"; + case stringIDToTypeID("saturation"): return "饱和度"; + case stringIDToTypeID("color"): return "颜色"; + case stringIDToTypeID("luminosity"): return "明度"; default: return "其他"; } } + // 外发光 图素方法 -function getOuterGlowTechniqueName(value) { - switch (value) { - case stringIDToTypeID("precise"): return "精确"; - case stringIDToTypeID("softer"): return "柔和"; - default: return "未知"; - } +function getOuterGlowTechniqueName(techniqueStr) { + var map = { + "softMatte": "柔和", + "preciseMatte": "精确" + }; + return map[techniqueStr] || techniqueStr; } + // 等高线名称(外发光等) function getContourName(value) { switch (value) { @@ -537,6 +808,12 @@ function getContourName(value) { } function colorDescToHex(colorDesc) { try { + if (!colorDesc.hasKey(stringIDToTypeID('red')) || + !colorDesc.hasKey(stringIDToTypeID('green')) || + !colorDesc.hasKey(stringIDToTypeID('blue'))) { + return null; + } + var red = Math.round(colorDesc.getDouble(stringIDToTypeID('red'))); var green = Math.round(colorDesc.getDouble(stringIDToTypeID('green'))); var blue = Math.round(colorDesc.getDouble(stringIDToTypeID('blue'))); @@ -545,6 +822,7 @@ function colorDescToHex(colorDesc) { return null; } } + function getInnerGlowTechniqueName(value) { switch(value) { case stringIDToTypeID("precise"): return "精确"; @@ -561,12 +839,13 @@ function getInnerGlowSourceName(value) { } 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(''); + function toHex(n) { + return ("0" + n.toString(16)).slice(-2); + } + return "#" + toHex(r) + toHex(g) + toHex(b); } + // 滤镜检测示例(只检测图层名包含的关键词) // 修改后的detectFilters函数,优先用XMP元数据读取镜头光晕参数 function detectFilters(layerName) { @@ -647,38 +926,6 @@ function readHistoryFromXMP() { -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) {