Files
pengchen-exam-java-localhost/checkPSD.jsx
2025-08-27 19:28:53 +08:00

1232 lines
48 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 简单 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 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);
if (layer.visible === true) {
info["可见"] = true;
}
if (layer.allLocked === true) {
info["锁定"] = true;
}
// 文字图层特殊信息
if (layer.kind === LayerKind.TEXT) {
var t = layer.textItem;
try {
info["文字内容"] = t.contents;
} catch (e) {
}
try {
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.tracking;}
catch (e) {
}
try {
if ('fauxItalic' in t && t.fauxItalic === true) {
info["仿斜体"] = true;
}
} catch (e) {}
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 styles = getLayerStyles(layer);
if (styles && !isEmptyObject(styles)) {
info["图层样式"] = styles;
}
var filterInfo = detectFilters(layer.name);
if (filterInfo && !isEmptyObject(filterInfo)) {
info["滤镜信息"] = filterInfo;
}
//蒙版
//蒙版操作 执行动作 创建 图层蒙版、 矢量蒙版、 剪切蒙版
// 🔹 蒙版
var maskInfo = getMaskInfo(layer);
if (maskInfo && !isEmptyObject(maskInfo)) {
info["蒙版类型"] = maskInfo;
}
// 选中当前图层为智能对象后
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 = {};
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")) {
jsonFile.encoding = "UTF8";
jsonFile.write(JSON.stringify(result, null, 2));
jsonFile.close();
// alert("JSON 文件已生成: " + jsonFilePath);
} else {
// 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);
//////////////////////////////////////////////
/////////////////////////////////////////////
// 辅助函数 - 颜色模式
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 getWarpTextProps() {
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
if (!desc.hasKey(stringIDToTypeID("textKey"))) return null;
var textDesc = desc.getObjectValue(stringIDToTypeID("textKey"));
if (!textDesc.hasKey(stringIDToTypeID("warp"))) return null;
var warpDesc = textDesc.getObjectValue(stringIDToTypeID("warp"));
// 样式汉化映射
var warpStyleMap = {
"warpNone":"无","warpArc":"弧形","warpArcLower":"下弧形","warpArcUpper":"上弧形",
"warpArch":"拱形","warpBulge":"凸出","warpShellLower":"下壳形","warpShellUpper":"上壳形",
"warpFlag":"旗帜","warpWave":"波浪","warpFish":"鱼形","warpRise":"上升",
"warpFisheye":"鱼眼","warpInflate":"膨胀","warpSqueeze":"挤压","warpTwist":"扭曲"
};
var warpStyleEn = warpDesc.hasKey(stringIDToTypeID("warpStyle")) ? typeIDToStringID(warpDesc.getEnumerationValue(stringIDToTypeID("warpStyle"))) : "warpNone";
var warpStyleCn = warpStyleMap[warpStyleEn] || warpStyleEn;
var warpBend = warpDesc.hasKey(stringIDToTypeID("warpValue")) ? warpDesc.getDouble(stringIDToTypeID("warpValue")) + "%" : "0%";
var horizontalKeys = ["horizontalDistortion", "horizontalDistortionValue","warpPerspective"];
var warpHorizontal = "0%";
for (var i=0;i<horizontalKeys.length;i++) {
if (warpDesc.hasKey(stringIDToTypeID(horizontalKeys[i]))) {
warpHorizontal = warpDesc.getDouble(stringIDToTypeID(horizontalKeys[i])) + "%";
break;
}
}
var verticalKeys = ["verticalDistortion", "verticalDistortionValue","warpPerspectiveOther"];
var warpVertical = "0%";
for (var i=0;i<verticalKeys.length;i++) {
if (warpDesc.hasKey(stringIDToTypeID(verticalKeys[i]))) {
warpVertical = warpDesc.getDouble(stringIDToTypeID(verticalKeys[i])) + "%";
break;
}
}
// 如果都是默认值,说明没有实际变形,返回 null
if (warpStyleCn === "无" && warpBend === "0%" && warpHorizontal === "0%" && warpVertical === "0%") {
return null;
}
return {
"样式": warpStyleCn,
"弯曲": warpBend,
"水平扭曲": warpHorizontal,
"垂直扭曲": warpVertical
};
}
function dumpDescriptor(desc, indent) {
indent = indent || "";
for (var i = 0; i < desc.count; i++) {
var key = desc.getKey(i);
var type = desc.getType(key);
var keyName = typeIDToStringID(key);
$.writeln(indent + keyName + " (" + type + ")");
try {
if (type == DescValueType.OBJECTTYPE) {
dumpDescriptor(desc.getObjectValue(key), indent + " ");
} else if (type == DescValueType.ENUMERATEDTYPE) {
$.writeln(indent + " value: " + typeIDToStringID(desc.getEnumerationValue(key)));
} else if (type == DescValueType.BOOLEANTYPE) {
$.writeln(indent + " value: " + desc.getBoolean(key));
} else if (type == DescValueType.DOUBLETYPE) {
$.writeln(indent + " value: " + desc.getDouble(key));
} else if (type == DescValueType.UNITDOUBLE) {
$.writeln(indent + " value: " + desc.getUnitDoubleValue(key));
} else if (type == DescValueType.STRINGTYPE) {
$.writeln(indent + " value: " + desc.getString(key));
} else if (type == DescValueType.INTEGERTYPE) {
$.writeln(indent + " value: " + desc.getInteger(key));
}
} catch(e) {
$.writeln(indent + " (无法读取: " + e + ")");
}
}
}
function dumpDescriptor(desc, indent) {
indent = indent || "";
for (var i = 0; i < desc.count; i++) {
var key = desc.getKey(i);
var type = desc.getType(key);
var keyName = typeIDToStringID(key);
$.writeln(indent + keyName + " (" + type + ")");
try {
if (type == DescValueType.OBJECTTYPE) {
dumpDescriptor(desc.getObjectValue(key), indent + " ");
} else if (type == DescValueType.ENUMERATEDTYPE) {
$.writeln(indent + " value: " + typeIDToStringID(desc.getEnumerationValue(key)));
} else if (type == DescValueType.BOOLEANTYPE) {
$.writeln(indent + " value: " + desc.getBoolean(key));
} else if (type == DescValueType.DOUBLETYPE) {
$.writeln(indent + " value: " + desc.getDouble(key));
} else if (type == DescValueType.UNITDOUBLE) {
$.writeln(indent + " value: " + desc.getUnitDoubleValue(key));
} else if (type == DescValueType.STRINGTYPE) {
$.writeln(indent + " value: " + desc.getString(key));
} else if (type == DescValueType.INTEGERTYPE) {
$.writeln(indent + " value: " + desc.getInteger(key));
}
} catch(e) {
$.writeln(indent + " (无法读取: " + e + ")");
}
}
}
function getLayerStyles(layer) {
var styles = {};
// ---- 激活图层 ----
app.activeDocument.activeLayer = layer;
// ---- 获取 ActionDescriptor ----
var desc;
try {
// 尝试 CC/2025 方法
var ref = new ActionReference();
if (layer.id !== undefined) {
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id);
} else {
throw "CS6 fallback";
}
desc = executeActionGet(ref);
} catch (e) {
// CS6 fallback
var ref2 = new ActionReference();
ref2.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
desc = executeActionGet(ref2);
}
// ---- 判断 layerEffects 是否存在 ----
if (!desc.hasKey(stringIDToTypeID("layerEffects"))) {
$.writeln("图层 " + layer.name + " 没有 layerEffects");
return styles; // 空对象
}
try {
var effects = desc.getObjectValue(stringIDToTypeID("layerEffects"));
// 用法:
if (effects.hasKey(stringIDToTypeID("bevelEmboss"))) {
var bevel = effects.getObjectValue(stringIDToTypeID("bevelEmboss"));
dumpDescriptor(bevel, ">> ");
}
// ---- 描边 ----
if (effects.hasKey(stringIDToTypeID("frameFX"))) {
var frameFX = effects.getObjectValue(stringIDToTypeID("frameFX"));
if (frameFX.hasKey(stringIDToTypeID("enabled"))) {
var enabled = frameFX.getBoolean(stringIDToTypeID("enabled"));
if (enabled) {
if (frameFX.hasKey(stringIDToTypeID("size"))) {
styles["描边_大小"] = frameFX.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素";
}
if (frameFX.hasKey(stringIDToTypeID("color"))) {
styles["描边_颜色"] = colorDescToHex(frameFX.getObjectValue(stringIDToTypeID("color")));
}
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("mode"))) {
styles["描边_混合模式"] = getBlendModeName(frameFX.getEnumerationValue(stringIDToTypeID("mode")));
}
}
}
}
// ---- 内发光 ----
if (effects.hasKey(stringIDToTypeID("innerGlow"))) {
var innerGlow = effects.getObjectValue(stringIDToTypeID("innerGlow"));
if (innerGlow.hasKey(stringIDToTypeID("enabled"))) {
var enabled = innerGlow.getBoolean(stringIDToTypeID("enabled"));
if (enabled) {
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("blur"))) {
styles["内发光_大小"] = innerGlow.getUnitDoubleValue(stringIDToTypeID("blur")) + " 像素";
}
if (innerGlow.hasKey(stringIDToTypeID("mode"))) {
var modeID = innerGlow.getEnumerationValue(stringIDToTypeID("mode"));
styles["内发光_混合模式"] = getBlendModeName(modeID);
}
if (innerGlow.hasKey(stringIDToTypeID("source"))) {
var source = innerGlow.getEnumerationValue(stringIDToTypeID("source"));
styles["内发光_来源"] = getInnerGlowSourceName(source);
}
}
}
}
// ---- 斜面和浮雕 ----
if (effects.hasKey(stringIDToTypeID("bevelEmboss"))) {
var bevel = effects.getObjectValue(stringIDToTypeID("bevelEmboss"));
if (bevel.hasKey(stringIDToTypeID("enabled"))) {
var enabled = bevel.getBoolean(stringIDToTypeID("enabled"));
if (enabled) {
var styleID = null;
if (bevel.hasKey(stringIDToTypeID("style"))) styleID = bevel.getEnumerationValue(stringIDToTypeID("style"));
else if (bevel.hasKey(stringIDToTypeID("bevelStyle"))) styleID = bevel.getEnumerationValue(stringIDToTypeID("bevelStyle"));
else if (bevel.hasKey(stringIDToTypeID("bevelTechnique"))) techniqueID = bevel.getEnumerationValue(stringIDToTypeID("bevelTechnique"));
if (styleID) styles["斜面和浮雕_样式"] = getBevelStyleName(typeIDToStringID(styleID));
// 读取斜面和浮雕方法
var techniqueID = null;
if (bevel.hasKey(stringIDToTypeID("technique"))) {
techniqueID = bevel.getEnumerationValue(stringIDToTypeID("technique"));
} else if (bevel.hasKey(stringIDToTypeID("bevelTechnique"))) {
techniqueID = bevel.getEnumerationValue(stringIDToTypeID("bevelTechnique"));
}
if (techniqueID) {
styles["斜面和浮雕_方法"] = getBevelTechniqueName(typeIDToStringID(techniqueID));
} else {
styles["斜面和浮雕_方法"] = "未知";
}
// 深度
if (bevel.hasKey(stringIDToTypeID("depth"))) {
styles["斜面和浮雕_深度"] = Math.round(bevel.getDouble(stringIDToTypeID("depth")) * 100) + "%";
} else if (bevel.hasKey(stringIDToTypeID("strengthRatio"))) {
styles["斜面和浮雕_深度"] = Math.round(bevel.getUnitDoubleValue(stringIDToTypeID("strengthRatio"))) + "%";
}
// 方向
if (bevel.hasKey(stringIDToTypeID("direction")) || bevel.hasKey(stringIDToTypeID("bevelDirection"))) {
var dir = bevel.hasKey(stringIDToTypeID("direction"))
? typeIDToStringID(bevel.getEnumerationValue(stringIDToTypeID("direction")))
: typeIDToStringID(bevel.getEnumerationValue(stringIDToTypeID("bevelDirection")));
styles["斜面和浮雕_方向"] = (dir === "up") ? "向上" : "向下";
}
// 大小
if (bevel.hasKey(stringIDToTypeID("size"))) {
styles["斜面和浮雕_大小"] = bevel.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素";
} else if (bevel.hasKey(stringIDToTypeID("blur"))) {
styles["斜面和浮雕_大小"] = bevel.getUnitDoubleValue(stringIDToTypeID("blur")) + " 像素";
}
// 软化
if (bevel.hasKey(stringIDToTypeID("soften")) || bevel.hasKey(stringIDToTypeID("softness"))) {
styles["斜面和浮雕_软化"] = bevel.hasKey(stringIDToTypeID("soften"))
? bevel.getUnitDoubleValue(stringIDToTypeID("soften")) + " 像素"
: bevel.getUnitDoubleValue(stringIDToTypeID("softness")) + " 像素";
}
// 使用全局光
if (bevel.hasKey(stringIDToTypeID("useGlobalAngle"))) {
styles["斜面和浮雕_使用全局光"] = bevel.getBoolean(stringIDToTypeID("useGlobalAngle")) ? "是" : "否";
}
// 角度
if (bevel.hasKey(stringIDToTypeID("localLightingAngle"))) {
styles["斜面和浮雕_角度"] = bevel.getInteger(stringIDToTypeID("localLightingAngle")) + "°";
}
// 高度
if (bevel.hasKey(stringIDToTypeID("localLightingAltitude"))) {
styles["斜面和浮雕_高度"] = bevel.getInteger(stringIDToTypeID("localLightingAltitude")) + "°";
}
// 等高线
if (bevel.hasKey(stringIDToTypeID("transparencyShape")) || bevel.hasKey(stringIDToTypeID("transferSpec"))) {
var contour = bevel.hasKey(stringIDToTypeID("transparencyShape"))
? bevel.getObjectValue(stringIDToTypeID("transparencyShape"))
: bevel.getObjectValue(stringIDToTypeID("transferSpec"));
styles["斜面和浮雕_等高线"] = contour.hasKey(stringIDToTypeID("name")) ? contour.getString(stringIDToTypeID("name")) : "未知";
} else {
styles["斜面和浮雕_等高线"] = "未知";
}
// 高光
if (bevel.hasKey(stringIDToTypeID("highlightMode"))) {
styles["斜面和浮雕_高光模式"] = getBlendModeName(bevel.getEnumerationValue(stringIDToTypeID("highlightMode")));
}
if (bevel.hasKey(stringIDToTypeID("highlightColor"))) {
styles["斜面和浮雕_高光颜色"] = colorDescToHex(bevel.getObjectValue(stringIDToTypeID("highlightColor")));
}
if (bevel.hasKey(stringIDToTypeID("highlightOpacity"))) {
styles["斜面和浮雕_高光不透明度"] = Math.round(bevel.getUnitDoubleValue(stringIDToTypeID("highlightOpacity"))) + "%";
}
// 阴影
if (bevel.hasKey(stringIDToTypeID("shadowMode"))) {
styles["斜面和浮雕_阴影模式"] = getBlendModeName(bevel.getEnumerationValue(stringIDToTypeID("shadowMode")));
}
if (bevel.hasKey(stringIDToTypeID("shadowColor"))) {
styles["斜面和浮雕_阴影颜色"] = colorDescToHex(bevel.getObjectValue(stringIDToTypeID("shadowColor")));
}
if (bevel.hasKey(stringIDToTypeID("shadowOpacity"))) {
styles["斜面和浮雕_阴影不透明度"] = Math.round(bevel.getUnitDoubleValue(stringIDToTypeID("shadowOpacity"))) + "%";
}
}
}
}
// ---- 外发光 ----
if (effects.hasKey(stringIDToTypeID("outerGlow"))) {
var outerGlow = effects.getObjectValue(stringIDToTypeID("outerGlow"));
if (outerGlow.hasKey(stringIDToTypeID("enabled"))) {
var enabled = outerGlow.getBoolean(stringIDToTypeID("enabled"));
if (enabled) {
// 不透明度
if (outerGlow.hasKey(stringIDToTypeID("opacity"))) {
styles["外发光_不透明度"] = Math.round(outerGlow.getUnitDoubleValue(stringIDToTypeID("opacity"))) + "%";
}
// 方法(精确 / 平滑)
if (outerGlow.hasKey(stringIDToTypeID("glowTechnique"))) {
var techEnum = outerGlow.getEnumerationValue(stringIDToTypeID("glowTechnique"));
styles["外发光_图素方法"] = getOuterGlowTechniqueName(typeIDToStringID(techEnum));
}
// 颜色(单色模式)
if (outerGlow.hasKey(stringIDToTypeID("color"))) {
styles["外发光_颜色"] = colorDescToHex(outerGlow.getObjectValue(stringIDToTypeID("color")));
}
// 大小
if (outerGlow.hasKey(stringIDToTypeID("blur"))) {
styles["外发光_大小"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("blur")) + " 像素";
}
// 阻塞
if (outerGlow.hasKey(stringIDToTypeID("chokeMatte"))) {
styles["外发光_阻塞"] = outerGlow.getUnitDoubleValue(stringIDToTypeID("chokeMatte")) + " 像素";
}
// 混合模式
if (outerGlow.hasKey(stringIDToTypeID("mode"))) {
styles["外发光_混合模式"] = getBlendModeName(outerGlow.getEnumerationValue(stringIDToTypeID("mode")));
}
// ---- 渐变信息 ----
if (outerGlow.hasKey(stringIDToTypeID("gradient"))) {
var gradient = outerGlow.getObjectValue(stringIDToTypeID("gradient"));
// 内部渐变名 ID
var gradientID = gradient.getString(stringIDToTypeID("name"));
// 常用渐变 ID -> 中文名映射表
var gradientNameMap = {
// 2025 版本直接英文名
"Chrome": "铬黄渐变",
"Black, White": "黑白渐变",
"Blue, Red": "蓝红渐变",
"Gold": "金色渐变",
"Silver": "银色渐变",
"Copper": "铜色渐变",
"Red, Yellow": "红黄渐变",
"Yellow, Green": "黄绿渐变",
"Green, Cyan": "绿青渐变",
"Cyan, Blue": "青蓝渐变",
"Magenta, Purple": "品紫渐变",
"Orange, Red": "橙红渐变",
"Blue, Purple": "蓝紫渐变",
"Foreground to Background": "前景到背景渐变",
"Black, Foreground": "黑到前景色渐变",
"Foreground to Transparent": "前景到透明渐变",
"Neutral Density": "中性密度渐变",
"Noise": "噪点渐变",
"Blue, Green": "蓝到绿渐变",
"Green, Yellow": "绿到黄渐变",
"Red, Blue": "红到蓝渐变",
"Yellow, Orange": "黄到橙渐变",
"Purple, Red": "紫到红渐变",
"White, Black": "白到黑渐变",
// CS6 及旧版 $$$ ID 格式
"$$$/DefaultGradient/Chrome=Chrome": "铬黄渐变",
"$$$/DefaultGradient/Black, White=Black, White": "黑白渐变",
"$$$/DefaultGradient/Blue, Red=Blue, Red": "蓝红渐变",
"$$$/DefaultGradient/Gold=Gold": "金色渐变",
"$$$/DefaultGradient/Silver=Silver": "银色渐变",
"$$$/DefaultGradient/Copper=Copper": "铜色渐变",
"$$$/DefaultGradient/Red, Yellow=Red, Yellow": "红黄渐变",
"$$$/DefaultGradient/Yellow, Green=Yellow, Green": "黄绿渐变",
"$$$/DefaultGradient/Green, Cyan=Green, Cyan": "绿青渐变",
"$$$/DefaultGradient/Cyan, Blue=Cyan, Blue": "青蓝渐变",
"$$$/DefaultGradient/Magenta, Purple=Magenta, Purple": "品紫渐变",
"$$$/DefaultGradient/Orange, Red=Orange, Red": "橙红渐变",
"$$$/DefaultGradient/Blue, Purple=Blue, Purple": "蓝紫渐变",
"$$$/DefaultGradient/Foreground to Background=前景到背景渐变": "前景到背景渐变",
"$$$/DefaultGradient/Black, Foreground=黑到前景色渐变": "黑到前景色渐变",
"$$$/DefaultGradient/Foreground to Transparent=前景到透明渐变": "前景到透明渐变",
"$$$/DefaultGradient/Neutral Density=Neutral Density": "中性密度渐变",
"$$$/DefaultGradient/Noise=Noise": "噪点渐变"
};
styles["外发光_渐变名称"] = gradientNameMap[gradientID] || gradientID;
// 颜色 stop
if (gradient.hasKey(stringIDToTypeID("colors"))) {
var colorsList = gradient.getList(stringIDToTypeID("colors"));
var colorHexArr = [];
for (var i = 0; i < colorsList.count; i++) {
var colorObj = colorsList.getObjectValue(i).getObjectValue(stringIDToTypeID("color"));
colorHexArr.push(colorDescToHex(colorObj));
}
styles["外发光_渐变色"] = colorHexArr;
}
}
}
}
}
// ---- 光泽Satin ----
if (effects.hasKey(stringIDToTypeID("satin"))) {
var satin = effects.getObjectValue(stringIDToTypeID("satin"));
if (satin.hasKey(stringIDToTypeID("enabled"))) {
var enabled = satin.getBoolean(stringIDToTypeID("enabled"));
if (enabled) {
if (satin.hasKey(stringIDToTypeID("opacity"))) {
styles["光泽_不透明度"] = Math.round(satin.getUnitDoubleValue(stringIDToTypeID("opacity"))) + "%";
}
if (satin.hasKey(stringIDToTypeID("color"))) {
styles["光泽_颜色"] = colorDescToHex(satin.getObjectValue(stringIDToTypeID("color")));
}
if (satin.hasKey(stringIDToTypeID("mode"))) {
styles["光泽_混合模式"] = getBlendModeName(satin.getEnumerationValue(stringIDToTypeID("mode")));
}
if (satin.hasKey(stringIDToTypeID("angle"))) {
styles["光泽_角度"] = satin.getUnitDoubleValue(stringIDToTypeID("angle")) + "°";
}
if (satin.hasKey(stringIDToTypeID("distance"))) {
styles["光泽_距离"] = satin.getUnitDoubleValue(stringIDToTypeID("distance")) + " 像素";
}
if (satin.hasKey(stringIDToTypeID("size"))) {
styles["光泽_大小"] = satin.getUnitDoubleValue(stringIDToTypeID("size")) + " 像素";
}
}
}
}
return hasOwnProperties(styles) ? styles : null;
} catch (e) {
return null;
}
}
// 辅助函数:描边位置
function getStrokePositionName(posStringID) {
switch(posStringID) {
case "outsetFrame": return "外侧";
case "insideFrame": return "内侧";
case "centeredFrame": 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 getBevelDirectionName(value) {
switch (value) {
case stringIDToTypeID("up"): return "上";
case stringIDToTypeID("down"): return "下";
default: return "未知";
}
}
// 图层混合模式
function getBlendModeName(value) {
var map = {
"normal": "正常",
"multiply": "正片叠底",
"screen": "滤色",
"overlay": "叠加",
"softLight": "柔光",
"hardLight": "强光",
"vividLight": "亮光",
"linearLight": "线性加深/减淡",
"pinLight": "点光",
"difference": "差值",
"exclusion": "排除",
"colorBurn": "颜色加深",
"linearBurn": "线性加深",
"darkerColor": "深色",
"colorDodge": "颜色减淡",
"linearDodge": "线性减淡",
"lighterColor": "浅色",
"lighten": "变亮",
"darken": "变暗",
"dissolve": "溶解",
"hue": "色相",
"saturation": "饱和度",
"color": "颜色",
"luminosity": "明度",
"subtract": "减去",
"blendSubtraction": "减去", // 2025 新增
"divide": "划分"
};
try {
// 可能是 stringID
var strID = (typeof value === "number") ? typeIDToStringID(value) : value;
return map[strID] || strID;
} catch(e) {
return value;
}
}
// 外发光 图素方法
function getOuterGlowTechniqueName(techniqueStr) {
var map = {
"softMatte": "柔和",
"preciseMatte": "精确"
};
return map[techniqueStr] || techniqueStr;
}
// 等高线名称(外发光等)
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 {
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')));
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) {
function toHex(n) {
return ("0" + n.toString(16)).slice(-2);
}
return "#" + toHex(r) + toHex(g) + toHex(b);
}
// 滤镜检测示例(只检测图层名包含的关键词)
// 修改后的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
};
}
}
// 判断对象是否含有自有属性兼容无Object.keys的环境
function hasOwnProperties(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return true;
}
}
return false;
}
function isEmptyObject(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) return false;
}
return true;
}
// ======================
// 获取蒙版信息
// ======================
function getMaskInfo(layer) {
var maskInfo = {};
try {
// 图层蒙版
if (hasLayerMask(layer)) {
maskInfo["图层蒙版"] = "存在";
}
// 矢量蒙版
if (hasVectorMask(layer)) {
maskInfo["矢量蒙版"] = "存在";
}
// 剪切蒙版
if (layer.grouped) { // ExtendScript 属性true 表示是剪切蒙版
maskInfo["剪切蒙版"] = "存在";
}
} catch (e) {
maskInfo["错误"] = e.toString();
}
return maskInfo;
}
// ======================
// 判断是否有图层蒙版
// ======================
function hasLayerMask(layer) {
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
return desc.hasKey(stringIDToTypeID("hasUserMask")) && desc.getBoolean(stringIDToTypeID("hasUserMask"));
}
// ======================
// 判断是否有矢量蒙版
// ======================
function hasVectorMask(layer) {
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
return desc.hasKey(stringIDToTypeID("hasVectorMask")) && desc.getBoolean(stringIDToTypeID("hasVectorMask"));
}
function getBevelStyleName(id) {
var map = {
"innerBevel": "内斜面",
"outerBevel": "外斜面",
"emboss": "浮雕",
"pillowEmboss": "枕状浮雕"
};
return map[id] || "未知";
}
function getBevelTechniqueName(id) {
var map = {
"smooth": "平滑",
"softMatte": "平滑", // 别名
"chiselSoft": "雕刻清晰",
"preciseMatte": "雕刻清晰", // 别名
"chiselHard": "雕刻深"
};
return map[id] || id || "未知";
}