adobe-ps-scripts-loreal/test/compare_layers.jsx
DJP 4a192a8c97 Initial commit: Adobe Photoshop API text management scripts
Local and cloud-based workflows for extracting and updating
text layers in PSD files via ExtendScript and Adobe PS API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:46:52 -05:00

229 lines
No EOL
7.7 KiB
JavaScript

// ExtendScript for comparing text layers between two PSD files
#target photoshop
// Function to extract text layers from a document
function extractTextLayers(doc) {
var result = {
documentName: doc.name,
textLayers: []
};
// Utility function to traverse layers
function traverseLayers(layers, path) {
path = path || "";
for (var i = 0; i < layers.length; i++) {
var layer = layers[i];
if (layer.typename === "LayerSet") {
// This is a layer group, traverse its children
var groupPath = path ? path + "/" + layer.name : layer.name;
traverseLayers(layer.layers, groupPath);
} else if (layer.kind === LayerKind.TEXT) {
// This is a text layer, extract its information
extractTextLayerInfo(layer, path);
}
}
}
function extractTextLayerInfo(layer, path) {
var layerPath = path ? path + "/" + layer.name : layer.name;
// Extract text content and basic info
var layerInfo = {
id: layer.id,
name: layer.name,
path: layerPath,
text: layer.textItem.contents,
visible: layer.visible
};
// Add to the result
result.textLayers.push(layerInfo);
}
// Start the traversal
traverseLayers(doc.layers);
return result;
}
// Function to compare text layers between two documents
function compareTextLayers(doc1Info, doc2Info) {
var results = [];
// Create dictionaries of layers by name for easier lookup
var doc1Layers = {};
var doc2Layers = {};
for (var i = 0; i < doc1Info.textLayers.length; i++) {
var layer = doc1Info.textLayers[i];
doc1Layers[layer.name] = layer;
}
for (var j = 0; j < doc2Info.textLayers.length; j++) {
var layer = doc2Info.textLayers[j];
doc2Layers[layer.name] = layer;
}
// First check original layers against processed
for (var name in doc1Layers) {
if (doc1Layers.hasOwnProperty(name)) {
var doc1Layer = doc1Layers[name];
if (doc2Layers[name]) {
var doc2Layer = doc2Layers[name];
// Check if the text content is different
if (doc1Layer.text !== doc2Layer.text) {
results.push({
name: name,
id1: doc1Layer.id,
id2: doc2Layer.id,
text1: doc1Layer.text,
text2: doc2Layer.text,
status: "modified"
});
} else {
results.push({
name: name,
id1: doc1Layer.id,
id2: doc2Layer.id,
text1: doc1Layer.text,
text2: doc2Layer.text,
status: "unchanged"
});
}
} else {
// Layer exists in doc1 but not in doc2
results.push({
name: name,
id1: doc1Layer.id,
id2: "N/A",
text1: doc1Layer.text,
text2: "LAYER MISSING",
status: "missing_in_doc2"
});
}
}
}
// Check for new layers in doc2 not in doc1
for (var name in doc2Layers) {
if (doc2Layers.hasOwnProperty(name) && !doc1Layers[name]) {
var doc2Layer = doc2Layers[name];
results.push({
name: name,
id1: "N/A",
id2: doc2Layer.id,
text1: "LAYER MISSING",
text2: doc2Layer.text,
status: "new_in_doc2"
});
}
}
return results;
}
// Main function
function main() {
if (app.documents.length < 1) {
alert("Please open at least one document before running this script.");
return;
}
try {
// Get the path to the first document (original)
var originalPath = app.activeDocument.fullName.fsName;
// Dialog to select the second document (processed)
var processedFile = File.openDialog("Select the processed PSD file to compare:", "*.psd");
if (!processedFile) {
alert("No processed file selected. Exiting.");
return;
}
// Extract text layers from the original document
var originalInfo = extractTextLayers(app.activeDocument);
// Remember the original document
var originalDoc = app.activeDocument;
// Open the processed document
app.open(processedFile);
// Extract text layers from the processed document
var processedInfo = extractTextLayers(app.activeDocument);
// Close the processed document
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Make sure the original document is active again
app.activeDocument = originalDoc;
// Compare the text layers
var comparisonResults = compareTextLayers(originalInfo, processedInfo);
// Generate the report
var report = "Text Layer Comparison Results\n";
report += "==================================================\n\n";
report += "Original PSD: " + originalPath + "\n";
report += "Processed PSD: " + processedFile.fsName + "\n\n";
// Count the differences
var modifiedCount = 0;
var missingCount = 0;
var newCount = 0;
var unchangedCount = 0;
for (var i = 0; i < comparisonResults.length; i++) {
var result = comparisonResults[i];
switch (result.status) {
case "modified": modifiedCount++; break;
case "missing_in_doc2": missingCount++; break;
case "new_in_doc2": newCount++; break;
case "unchanged": unchangedCount++; break;
}
}
report += "SUMMARY:\n";
report += " Total text layers compared: " + comparisonResults.length + "\n";
report += " Modified layers: " + modifiedCount + "\n";
report += " Missing in processed: " + missingCount + "\n";
report += " New in processed: " + newCount + "\n";
report += " Unchanged layers: " + unchangedCount + "\n\n";
report += "DETAILS:\n";
report += "==================================================\n\n";
// Add details for each comparison
for (var i = 0; i < comparisonResults.length; i++) {
var result = comparisonResults[i];
report += "Layer: " + result.name + "\n";
report += " Status: " + result.status + "\n";
report += " Original ID: " + result.id1 + "\n";
report += " Processed ID: " + result.id2 + "\n";
report += " Original text: \"" + result.text1 + "\"\n";
report += " Processed text: \"" + result.text2 + "\"\n";
report += "-------------------------------------------------\n\n";
}
// Save the report to a text file next to the original PSD
var reportFolder = originalDoc.path;
var reportFile = new File(reportFolder + "/text_layer_comparison.txt");
reportFile.open("w");
reportFile.write(report);
reportFile.close();
alert("Comparison complete! Report saved to:\n" + reportFile.fsName);
} catch (e) {
alert("Error: " + e.message);
}
}
// Run the main function
main();