#target indesign #targetengine "bgLinkUI" (function () { if ($.global.bgLinkUI && $.global.bgLinkUI instanceof Window) { try { $.global.bgLinkUI.show(); $.global.bgLinkUI.active = true; return; } catch (e0) {} } function qq(s) { return '"' + String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"'; } function pageItemFromLink(link) { try { return link.parent.parent; } catch (e) { return null; } } function isSupportedLink(link) { try { return /\.(jpg|jpeg|png|tif|tiff|psd|bmp)$/i.test(link.name); } catch (e) { return false; } } function labelFor(link) { var t = link.name; try { var it = pageItemFromLink(link); if (it && it.parentPage) t += " — Page " + it.parentPage.name; } catch (e) {} return t; } function photoshopAvailable() { try { return BridgeTalk.getSpecifier("photoshop") !== null; } catch (e) { return false; } } var w = new Window("palette", "Links: Remove Background"); $.global.bgLinkUI = w; w.orientation = "column"; w.alignChildren = "fill"; w.spacing = 8; w.margins = 12; w.add("statictext", undefined, "Scan links, choose one, then select it or remove background + relink."); var lb = w.add("listbox", undefined, [], {multiselect:false}); lb.preferredSize = [560, 280]; var g = w.add("group"); g.orientation = "row"; var bScan = g.add("button", undefined, "Scan Links"); var bSelect = g.add("button", undefined, "Select Link"); var bRun = g.add("button", undefined, "Remove BG + Relink"); var status = w.add("statictext", undefined, "Ready"); status.characters = 75; w._links = []; function refreshLinks() { lb.removeAll(); w._links = []; if (app.documents.length === 0) { status.text = "Open an InDesign document first."; return; } var doc = app.activeDocument; var i, ln; for (i = 0; i < doc.links.length; i++) { ln = doc.links[i]; if (isSupportedLink(ln)) { w._links.push(ln); lb.add("item", labelFor(ln)); } } if (w._links.length > 0) { lb.selection = 0; status.text = "Found " + w._links.length + " supported image links."; } else { status.text = "No supported raster links found."; } } function currentLink() { if (!lb.selection) return null; return w._links[lb.selection.index]; } function selectChosenLink() { var link = currentLink(); if (!link) { alert("Choose a link first."); return; } if (app.layoutWindows.length === 0) { alert("Open a document window first."); return; } try { var it = pageItemFromLink(link); if (!it || !it.isValid) { alert("Could not locate the page item for this link."); return; } try { if (it.parentPage) app.activeWindow.activePage = it.parentPage; } catch (e1) {} app.select(it); status.text = "Selected: " + link.name; } catch (e) { alert("Could not select that link:\r" + e); } } function runRemoveBackground() { var link = currentLink(); if (!link) { alert("Choose a link first."); return; } if (!photoshopAvailable()) { alert("Photoshop is not available to BridgeTalk."); return; } var src; try { src = File(link.filePath); } catch (e0) { alert("Could not read the link file path."); return; } if (!src || !src.exists) { alert("Link file not found:\r" + (src ? src.fsName : "[unknown]")); return; } var base = src.name.replace(/\.[^\.]+$/, ""); var out = File(src.path + "/" + base + "_nobg.psd"); status.text = "Sending to Photoshop..."; var ps = []; ps.push("app.displayDialogs = DialogModes.NO;"); ps.push("var inFile = File(" + qq(src.fsName) + ");"); ps.push("var outFile = File(" + qq(out.fsName) + ");"); ps.push("if (!inFile.exists) throw new Error('Input file missing: ' + inFile.fsName);"); ps.push("var doc = app.open(inFile);"); ps.push("try { if (doc.activeLayer.isBackgroundLayer) doc.activeLayer.isBackgroundLayer = false; } catch(e) {}"); // Try Remove Background first, then Select Subject fallback ps.push("var ok = false;"); ps.push("try { executeAction(stringIDToTypeID('autoCutout'), new ActionDescriptor(), DialogModes.NO); ok = true; } catch(e1) {}"); ps.push("if (!ok) { try { executeAction(stringIDToTypeID('selectSubject'), new ActionDescriptor(), DialogModes.NO); ok = true; } catch(e2) {} }"); ps.push("if (!ok) throw new Error('Remove Background / Select Subject is unavailable in Photoshop.');"); // Make layer mask from selection ps.push("var d = new ActionDescriptor();"); ps.push("d.putClass(charIDToTypeID('Nw '), charIDToTypeID('Chnl'));"); ps.push("var r = new ActionReference();"); ps.push("r.putEnumerated(charIDToTypeID('Chnl'), charIDToTypeID('Chnl'), charIDToTypeID('Msk '));"); ps.push("d.putReference(charIDToTypeID('At '), r);"); ps.push("d.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('UsrM'), charIDToTypeID('RvlS'));"); ps.push("executeAction(charIDToTypeID('Mk '), d, DialogModes.NO);"); ps.push("try { doc.trim(TrimType.TRANSPARENT, true, true, true, true); } catch(e3) {}"); ps.push("var o = new PhotoshopSaveOptions();"); ps.push("o.layers = true;"); ps.push("o.embedColorProfile = true;"); ps.push("doc.saveAs(outFile, o, true, Extension.LOWERCASE);"); ps.push("doc.close(SaveOptions.DONOTSAVECHANGES);"); ps.push("outFile.fsName.toSource();"); var bt = new BridgeTalk(); bt.target = "photoshop"; bt.body = ps.join("\n"); bt.onResult = function (res) { try { var newPath = eval(res.body); var f = File(newPath); if (!f.exists) { alert("PSD was not created."); status.text = "PSD missing."; return; } link.relink(f); try { link.update(); } catch (e4) {} status.text = "Done: " + f.name; refreshLinks(); } catch (e5) { alert("Photoshop finished, but relink failed:\r" + e5); status.text = "Relink failed."; } }; bt.onError = function (err) { alert("BridgeTalk / Photoshop error:\r" + err.body); status.text = "Photoshop error."; }; bt.send(); } bScan.onClick = refreshLinks; bSelect.onClick = selectChosenLink; bRun.onClick = runRemoveBackground; w.onShow = function () { refreshLinks(); }; w.center(); w.show(); })();