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>
229 lines
No EOL
7.7 KiB
JavaScript
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(); |