I was wondering if it's possible to create a script that does this:
I have one layer that has merged images on it....where I have 10 phones with transparent background.
I'd like to select this one layer and have the script cut out each phone and make 10 separate layers on the same document.
and if possible, it would also maintain the original position of each phone on the canvas...
Script for Splitting Layers
-
pfaffenbichler
Script for Splitting Layers
Check out this thread:
http://forums.adobe.com/message/4272787#4272787
Edit: The distance between the objects on the Layer is relevant, though, so you may have to adjust the part of the Script regarding the expansion of the Selection.
http://forums.adobe.com/message/4272787#4272787
Edit: The distance between the objects on the Layer is relevant, though, so you may have to adjust the part of the Script regarding the expansion of the Selection.
-
mycort
Script for Splitting Layers
truly impressive and exactly what i envisioned this to be...even retains the exact location.
When i did apply to a bigger layer with many images, it did give me an error dialog and crashes......any thoughts on why this happens and is there a work around this problem?
see my attached file.
When i did apply to a bigger layer with many images, it did give me an error dialog and crashes......any thoughts on why this happens and is there a work around this problem?
see my attached file.
-
pfaffenbichler
Script for Splitting Layers
Could you please post an image on which it crashes? (Feel free to blacken the RGB-channels, it’s just the Layer’s transparency that should matter.)
-
mycort
Script for Splitting Layers
Seems like the psd file is too big for attaching here, so here's an ftp site where you can download this file from: http://EmailLargeFile.com/d/DEAUL3KLMZS
It's a psd file with a bunch of phones on a single layer and just want to split all the phones onto separate layers......
It's a psd file with a bunch of phones on a single layer and just want to split all the phones onto separate layers......
-
pfaffenbichler
Script for Splitting Layers
I think it did not actually crash, but the function to collect the path’s info ran so slow that it seemed like that.
I have a newer function that uses Action Manager code instead of just using the DOM – that runs faster.
Also you could increase the number in
Code: Select allif (subPathsNumber > 30) {
, so that you will not be prompted with the confirm-dialog, or remove that check completely.
If there is a high number of Layers resulting from selecting noise or artifacts you could try for example using the Filter Dust & Scratches on the channel.
Please try this:
Code: Select all// lift discontinuous content from layer onto individual layers;
// for rgb-images and cs5;
// 2012, use it at your own risk;
#target photoshop
if (app.documents.length > 0 && app.activeDocument.mode = DocumentMode.RGB) {
myDocument = app.activeDocument;
myDocument.activeChannels = [myDocument.channels[0], myDocument.channels[1], myDocument.channels[2]];
// load transarency;
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc11 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref6 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref6.putProperty( idChnl, idfsel );
desc11.putReference( idnull, ref6 );
var idT = charIDToTypeID( "T " );
var ref7 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idTrsp = charIDToTypeID( "Trsp" );
ref7.putEnumerated( idChnl, idChnl, idTrsp );
desc11.putReference( idT, ref7 );
executeAction( idsetd, desc11, DialogModes.NO );
//
var check = true;
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// set to 72ppi;
var originalResolution = app.activeDocument.resolution;
myDocument.resizeImage (undefined, undefined, 72, ResampleMethod.NONE);
//
var theMask = myDocument.channels.add();
myDocument.selection.store(theMask);
myDocument.activeChannels = [myDocument.channels[0], myDocument.channels[1], myDocument.channels[2]];
var theLayer = myDocument.activeLayer;
myDocument.selection.load(theMask, SelectionType.REPLACE);
// use threshold to heighten non black pixels;
myDocument.quickMaskMode = true;
myDocument.activeLayer.threshold(1);
myDocument.quickMaskMode = false;
// create work path;
myDocument.selection.makeWorkPath(1);
var subPathsNumber = myDocument.pathItems[myDocument.pathItems.length-1].subPathItems.length;
// check for a high number of paths;
if (subPathsNumber > 30) {
check = confirm("warning\rthere appear to be "+subPathsNumber+" elements.\rif this number is too high noise may have caused them.\rthis may result in a crash.\rproceed?")
};
// do the operation;
if (check == true) {
var thePathInfo = collectPathInfoFromDesc2012(myDocument, myDocument.pathItems[myDocument.pathItems.length-1]);
// create one path for every subpathitem:
for (var m = 0; m < thePathInfo.length; m++) {
var theSubPath = thePathInfo[m];
var aPath = createPath2012 ([theSubPath], m+"_path");
aPath.makeSelection(0, true, SelectionType.REPLACE);
// expand;
myDocument.selection.expand(6);
myDocument.selection.load(theMask, SelectionType.INTERSECT);
// layer via copy;
try {
var id14 = charIDToTypeID( "CpTL" );
executeAction( id14, undefined, DialogModes.NO );
myDocument.activeLayer.name = theLayer.name + "_" + (m+1)
}
catch (e) {};
myDocument.pathItems[myDocument.pathItems.length-1].remove();
myDocument.activeLayer = theLayer;
};
theLayer.visible = false;
};
// reset;
app.preferences.rulerUnits = originalRulerUnits;
myDocument.resizeImage (undefined, undefined, originalResolution, ResampleMethod.NONE);
};
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////// collect path info from actiondescriptor, smooth added //////
function collectPathInfoFromDesc2012 (myDocument, thePath) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
for (var l = 0; l < myDocument.pathItems.length; l++) {
var thisPath = myDocument.pathItems[l];
if (thisPath == thePath && thisPath.name == "Work Path") {
ref.putProperty(cTID("Path"), cTID("WrPt"));
};
if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {
ref.putIndex(cTID("Path"), l + 1);
};
if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {
var idPath = charIDToTypeID( "Path" );
var idPath = charIDToTypeID( "Path" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
ref.putEnumerated( idPath, idPath, idvectorMask );
};
};
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
switch (operation1) {
case 1097098272:
var operation = 1097098272 //cTID('Add ');
break;
case 1398961266:
var operation = 1398961266 //cTID('Sbtr');
break;
case 1231975538:
var operation = 1231975538 //cTID('Intr');
break;
default:
// case 1102:
var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
break;
};
// for subpathitem’s count;
for (var n = 0; n < listKey.count; n++) {
theArray.push(new Array);
var points = listKey.getObjectValue(n).getList(sTID('points'));
try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
catch (e) {var closed = false};
// for subpathitem’s segment’s number of points;
for (var o = 0; o < points.count; o++) {
var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
var thisPoint = [anchor];
try {
var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
thisPoint.push(leftDirection)
}
catch (e) {
thisPoint.push(anchor)
};
try {
var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
thisPoint.push(rightDirection)
}
catch (e) {
thisPoint.push(anchor)
};
try {
var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
thisPoint.push(smoothOr)
}
catch (e) {thisPoint.push(false)};
theArray[theArray.length - 1].push(thisPoint);
};
theArray[theArray.length - 1].push(closed);
theArray[theArray.length - 1].push(operation);
};
};
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// create a path from collectPathInfoFromDesc2012-array //////
function createPath2012(theArray, thePathsName) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// thanks to xbytor;
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(cTID('Path'), cTID('WrPt'));
desc1.putReference(sTID('null'), ref1);
var list1 = new ActionList();
for (var m = 0; m < theArray.length; m++) {
var thisSubPath = theArray[m];
var desc2 = new ActionDescriptor();
desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
var list2 = new ActionList();
var desc3 = new ActionDescriptor();
desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
var list3 = new ActionList();
for (var n = 0; n < thisSubPath.length - 2; n++) {
var thisPoint = thisSubPath[n];
var desc4 = new ActionDescriptor();
var desc5 = new ActionDescriptor();
desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
var desc6 = new ActionDescriptor();
desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
var desc7 = new ActionDescriptor();
desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
list3.putObject(cTID('Pthp'), desc4);
};
desc3.putList(cTID('Pts '), list3);
list2.putObject(cTID('Sbpl'), desc3);
desc2.putList(cTID('SbpL'), list2);
list1.putObject(cTID('PaCm'), desc2);
};
desc1.putList(cTID('T '), list1);
executeAction(cTID('setd'), desc1, DialogModes.NO);
if (hasVectorMask() == false) {
app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].name = thePathsName;
var myPathItem = app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1];
}
else {
app.activeDocument.pathItems[app.activeDocument.pathItems.length - 2].name = thePathsName;
var myPathItem = app.activeDocument.pathItems[app.activeDocument.pathItems.length - 2];
};
app.preferences.rulerUnits = originalRulerUnits;
return myPathItem
};
// from »Flatten All Masks.jsx« by jeffrey tranberry;
///////////////////////////////////////////////////////////////////////////////
// Function: hasVectorMask
// Usage: see if there is a vector layer mask
// Input: <none> Must have an open document
// Return: true if there is a vector mask
///////////////////////////////////////////////////////////////////////////////
function hasVectorMask() {
var hasVectorMask = false;
try {
var ref = new ActionReference();
var keyVectorMaskEnabled = app.stringIDToTypeID( 'vectorMask' );
var keyKind = app.charIDToTypeID( 'Knd ' );
ref.putEnumerated( app.charIDToTypeID( 'Path' ), app.charIDToTypeID( 'Ordn' ), keyVectorMaskEnabled );
var desc = executeActionGet( ref );
if ( desc.hasKey( keyKind ) ) {
var kindValue = desc.getEnumerationValue( keyKind );
if (kindValue == keyVectorMaskEnabled) {
hasVectorMask = true;
}
}
}catch(e) {
hasVectorMask = false;
}
return hasVectorMask;
};
I have a newer function that uses Action Manager code instead of just using the DOM – that runs faster.
Also you could increase the number in
Code: Select allif (subPathsNumber > 30) {
, so that you will not be prompted with the confirm-dialog, or remove that check completely.
If there is a high number of Layers resulting from selecting noise or artifacts you could try for example using the Filter Dust & Scratches on the channel.
Please try this:
Code: Select all// lift discontinuous content from layer onto individual layers;
// for rgb-images and cs5;
// 2012, use it at your own risk;
#target photoshop
if (app.documents.length > 0 && app.activeDocument.mode = DocumentMode.RGB) {
myDocument = app.activeDocument;
myDocument.activeChannels = [myDocument.channels[0], myDocument.channels[1], myDocument.channels[2]];
// load transarency;
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc11 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref6 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref6.putProperty( idChnl, idfsel );
desc11.putReference( idnull, ref6 );
var idT = charIDToTypeID( "T " );
var ref7 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idTrsp = charIDToTypeID( "Trsp" );
ref7.putEnumerated( idChnl, idChnl, idTrsp );
desc11.putReference( idT, ref7 );
executeAction( idsetd, desc11, DialogModes.NO );
//
var check = true;
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// set to 72ppi;
var originalResolution = app.activeDocument.resolution;
myDocument.resizeImage (undefined, undefined, 72, ResampleMethod.NONE);
//
var theMask = myDocument.channels.add();
myDocument.selection.store(theMask);
myDocument.activeChannels = [myDocument.channels[0], myDocument.channels[1], myDocument.channels[2]];
var theLayer = myDocument.activeLayer;
myDocument.selection.load(theMask, SelectionType.REPLACE);
// use threshold to heighten non black pixels;
myDocument.quickMaskMode = true;
myDocument.activeLayer.threshold(1);
myDocument.quickMaskMode = false;
// create work path;
myDocument.selection.makeWorkPath(1);
var subPathsNumber = myDocument.pathItems[myDocument.pathItems.length-1].subPathItems.length;
// check for a high number of paths;
if (subPathsNumber > 30) {
check = confirm("warning\rthere appear to be "+subPathsNumber+" elements.\rif this number is too high noise may have caused them.\rthis may result in a crash.\rproceed?")
};
// do the operation;
if (check == true) {
var thePathInfo = collectPathInfoFromDesc2012(myDocument, myDocument.pathItems[myDocument.pathItems.length-1]);
// create one path for every subpathitem:
for (var m = 0; m < thePathInfo.length; m++) {
var theSubPath = thePathInfo[m];
var aPath = createPath2012 ([theSubPath], m+"_path");
aPath.makeSelection(0, true, SelectionType.REPLACE);
// expand;
myDocument.selection.expand(6);
myDocument.selection.load(theMask, SelectionType.INTERSECT);
// layer via copy;
try {
var id14 = charIDToTypeID( "CpTL" );
executeAction( id14, undefined, DialogModes.NO );
myDocument.activeLayer.name = theLayer.name + "_" + (m+1)
}
catch (e) {};
myDocument.pathItems[myDocument.pathItems.length-1].remove();
myDocument.activeLayer = theLayer;
};
theLayer.visible = false;
};
// reset;
app.preferences.rulerUnits = originalRulerUnits;
myDocument.resizeImage (undefined, undefined, originalResolution, ResampleMethod.NONE);
};
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////// collect path info from actiondescriptor, smooth added //////
function collectPathInfoFromDesc2012 (myDocument, thePath) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
for (var l = 0; l < myDocument.pathItems.length; l++) {
var thisPath = myDocument.pathItems[l];
if (thisPath == thePath && thisPath.name == "Work Path") {
ref.putProperty(cTID("Path"), cTID("WrPt"));
};
if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {
ref.putIndex(cTID("Path"), l + 1);
};
if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {
var idPath = charIDToTypeID( "Path" );
var idPath = charIDToTypeID( "Path" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
ref.putEnumerated( idPath, idPath, idvectorMask );
};
};
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
switch (operation1) {
case 1097098272:
var operation = 1097098272 //cTID('Add ');
break;
case 1398961266:
var operation = 1398961266 //cTID('Sbtr');
break;
case 1231975538:
var operation = 1231975538 //cTID('Intr');
break;
default:
// case 1102:
var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
break;
};
// for subpathitem’s count;
for (var n = 0; n < listKey.count; n++) {
theArray.push(new Array);
var points = listKey.getObjectValue(n).getList(sTID('points'));
try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
catch (e) {var closed = false};
// for subpathitem’s segment’s number of points;
for (var o = 0; o < points.count; o++) {
var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
var thisPoint = [anchor];
try {
var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
thisPoint.push(leftDirection)
}
catch (e) {
thisPoint.push(anchor)
};
try {
var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
thisPoint.push(rightDirection)
}
catch (e) {
thisPoint.push(anchor)
};
try {
var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
thisPoint.push(smoothOr)
}
catch (e) {thisPoint.push(false)};
theArray[theArray.length - 1].push(thisPoint);
};
theArray[theArray.length - 1].push(closed);
theArray[theArray.length - 1].push(operation);
};
};
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// create a path from collectPathInfoFromDesc2012-array //////
function createPath2012(theArray, thePathsName) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// thanks to xbytor;
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(cTID('Path'), cTID('WrPt'));
desc1.putReference(sTID('null'), ref1);
var list1 = new ActionList();
for (var m = 0; m < theArray.length; m++) {
var thisSubPath = theArray[m];
var desc2 = new ActionDescriptor();
desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
var list2 = new ActionList();
var desc3 = new ActionDescriptor();
desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
var list3 = new ActionList();
for (var n = 0; n < thisSubPath.length - 2; n++) {
var thisPoint = thisSubPath[n];
var desc4 = new ActionDescriptor();
var desc5 = new ActionDescriptor();
desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
var desc6 = new ActionDescriptor();
desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
var desc7 = new ActionDescriptor();
desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
list3.putObject(cTID('Pthp'), desc4);
};
desc3.putList(cTID('Pts '), list3);
list2.putObject(cTID('Sbpl'), desc3);
desc2.putList(cTID('SbpL'), list2);
list1.putObject(cTID('PaCm'), desc2);
};
desc1.putList(cTID('T '), list1);
executeAction(cTID('setd'), desc1, DialogModes.NO);
if (hasVectorMask() == false) {
app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].name = thePathsName;
var myPathItem = app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1];
}
else {
app.activeDocument.pathItems[app.activeDocument.pathItems.length - 2].name = thePathsName;
var myPathItem = app.activeDocument.pathItems[app.activeDocument.pathItems.length - 2];
};
app.preferences.rulerUnits = originalRulerUnits;
return myPathItem
};
// from »Flatten All Masks.jsx« by jeffrey tranberry;
///////////////////////////////////////////////////////////////////////////////
// Function: hasVectorMask
// Usage: see if there is a vector layer mask
// Input: <none> Must have an open document
// Return: true if there is a vector mask
///////////////////////////////////////////////////////////////////////////////
function hasVectorMask() {
var hasVectorMask = false;
try {
var ref = new ActionReference();
var keyVectorMaskEnabled = app.stringIDToTypeID( 'vectorMask' );
var keyKind = app.charIDToTypeID( 'Knd ' );
ref.putEnumerated( app.charIDToTypeID( 'Path' ), app.charIDToTypeID( 'Ordn' ), keyVectorMaskEnabled );
var desc = executeActionGet( ref );
if ( desc.hasKey( keyKind ) ) {
var kindValue = desc.getEnumerationValue( keyKind );
if (kindValue == keyVectorMaskEnabled) {
hasVectorMask = true;
}
}
}catch(e) {
hasVectorMask = false;
}
return hasVectorMask;
};
-
mycort
Script for Splitting Layers
works perfectly now, much faster and does it in real time, i've also removed the error code. a great and truly impressive script man.
On a slightly different but similar topic, remember the text splitter script I posted earlier regarding having the ability to combine....but you noted it can be done it's just that you will lose any other text styles(font type, size, color...etc) once it does split/combine. Since you made a break through in reading several different type fonts on one line in my Pixel Measure Script, is it possible to somehow implement this code into this text split/combine script now?
Here's the Text Splitter Code:
Code: Select alldoc = app.activeDocument;
layer = doc.activeLayer;
var text = layer.textItem.contents;
var textArray = text.split("\r");
var pos = layer.textItem.position;
var leading = 0;
if (layer.textItem.useAutoLeading){
leading = layer.textItem.size/100*Math.round(layer.textItem.autoLeadingAmount)
}
else{
leading = Number(layer.textItem.leading)
}
layer.textItem.contents=textArray[0]
layer.name = textArray[0]
for (var k=1; k<textArray.length;k++){
tmp = layer.duplicate();
tmp.textItem.position = [pos[0], pos[1]+(Number(leading)*k)]
tmp.textItem.contents = textArray[k];
}
Pixel Measure Spec Script with Font Reader at the bottom:
Code: Select all /*
DISCLAIMER / TERMS & CONDITIONS / CREDITS
---------------------------------------------------------------------------------------------------------------------------------------------------
Pixel Measure v0.04 - Photoshop script for adding pixel measurements to your mockups
Copyright (C) 2009 Nikolaj Selvik
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
---------------------------------------------------------------------------------------------------------------------------------------------------
Updated by Bezzy Weitz (Magical Coder - a million thx for his time) & Mycort (GUI Artist & Idea Man)
Creators of functions 3 -> 7 (4/15/2012 - v0.05). Specifc code edits and additions include:
- 4 measures using "L"shaped selection
- 2 measures using crosshair selections
- 6 measures of inner/outer box
- Simultaneous Measure (Vert & Horiz -All at once)
- Arrow edge drawing (toggle function)
- Adding "var" section for easier editing of toggled functions
- Long extended edge line (8 point Detection Function)
Code snippets and advice help courtesy of (bb/)
- Working code for converting selection to paths to detect values of simultaneous measures
- Centering of labels/cut line
- Making the code faster with the addition of Script Listener
- In multiple measures mode, new function to link both lines/label together for easier movement
- Font analyzer, creation of text layer info, multiple selection
Font-detection system updated by Maksim Izmaylov <me@kvakes.com> in 2012.
==========================================================================================
Got questions or suggestions for further improvement?
- Contact me at: mycort@yahoo.com
- A little plug for my portfolio site: mycort.deviantart.com/gallery
==========================================================================================
Great many thanks to Nikolaj Selvik, the developer who first and initially created this time saving tool.
- Original creator of functions 1 & 2 (Horizontal & vertical "single" selection)
- Uncentered Label
- Line edge drawing
---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#target photoshop
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Toggle functions (put true or false here to turn on/off features)
var make_arrows = true;
var make_centered_labels = true;
var make_bold_labels = true;
var use_fast_draw = false;
var LinkLayers = false;
var font_size = 10;
var arrow_size = 3;
var font_content_detection = true;
var font_content_detection_symbols = ['(', ')'];
var TextLeading =true;
var TextJustification =true;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var mainLayerSet;
var layerSetRef;
var rectInfo;
var rectangleList;
var originalUnit = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var myDocument = app.activeDocument;
var theLayer = myDocument.activeLayer;
var myDoc = app.activeDocument;
var myLayer = myDoc.activeLayer;
var origResolution = myDocument.resolution;
myDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);
app.displayDialogs = DialogModes.NO;
if (validateState()) {
app.activeDocument.suspendHistory("Pixel Specs", "pm();");
};
myDocument.resolution = origResolution;
function pm() {
// =======================================================
// Create Layer Sets
// =======================================================
try {
mainLayerSet = app.activeDocument.layerSets.getByName("Pixel Specs");
} catch (error) {
mainLayerSet = app.activeDocument.layerSets.add();
mainLayerSet.name = "Pixel Specs";
}
layerSetRef = mainLayerSet.layerSets.add();
// Determine how many independent rectangles exist in the selection
rectInfo = getRectangles();
rectangleList = rectInfo.bounds;
if (rectangleList.length == 2 && (is_inside(rectangleList[0], rectangleList[1]) || is_inside(rectangleList[1], rectangleList[0]))) createMeasure();
else if (rectangleList.length == 1) {
if (rectInfo.longinfo[0] === false) createMeasure();
else createLongLabel(rectInfo.longinfo[0]);
} else if (rectangleList.length > 1) createMultipleMeasures();
app.activeDocument.selection.deselect();
if (rectangleList.length > 1) {
layerSetRef.name = "Multiple Measures";
}
}
// Linking function of multiple measures
if (LinkLayers) {
if (activeDocument.activeLayer.typename != "LayerSet") {
if (activeDocument.activeLayer.parent.typename = "LayerSet") {
activeDocument.activeLayer = activeDocument.activeLayer.parent;
}
if (rectangleList.length > 1) {
var doc = activeDocument;
var thisSet = doc.activeLayer;
var LayerList = new Array();
for (var a = 0; a < thisSet.layers.length; a++) {
activeDocument.activeLayer = thisSet.layers[a];
LayerList.push(getActiveLayerIndex());
}
while (LayerList.length > 0) {
selectLayerByIndex(Number(LayerList.shift()));
selectLayerByIndex(Number(LayerList.shift()), true);
linkSelectedLayers();
}
}
}
}
function validateState() {
if (app.documents.length == 0) {
alert("No document open");
return false;
}
if (!hasSelection(app.activeDocument)) {
if (myLayer.kind == LayerKind.TEXT) {
multiselectfontreader();
return false
} else {
loadTransparency()
}
}
return true;
}
function is_inside(r1, r2) {
return r1[0] <= r2[0] && r1[1] <= r2[1] && r1[2] >= r2[2] && r1[3] >= r2[3];
}
function createMultipleMeasures() {
for (var i = 0; i < rectangleList.length; i++) {
if (rectInfo.longinfo === false) {
if (rectangleList[2] - rectangleList[0] > rectangleList[3] - rectangleList[1]) createLabel(rectangleList[0], parseInt(rectangleList[1] + (rectangleList[3] - rectangleList[1]) / 2) - 5, rectangleList[2], parseInt(rectangleList[i][1] + (rectangleList[i][3] - rectangleList[i][1]) / 2) + 5, true);
else createLabel(parseInt(rectangleList[i][0] + (rectangleList[i][2] - rectangleList[i][0]) / 2) - 5, rectangleList[i][1], parseInt(rectangleList[i][0] + (rectangleList[i][2] - rectangleList[i][0]) / 2) + 5, rectangleList[i][3], false);
} else {
createLongLabel(rectInfo.longinfo[i]);
}
}
}
function createMeasure() {
var docRef = app.activeDocument;
var selRef = docRef.selection;
var channelRef;
var is_rect = false;
// =======================================================
// Set Up Selection
// =======================================================
var fx1 = selRef.bounds[0].value;
var fy1 = selRef.bounds[1].value;
var fx2 = selRef.bounds[2].value;
var fy2 = selRef.bounds[3].value;
try {
channelRef = docRef.channels.getByName("Pixel Specs");
} catch (error) {
channelRef = docRef.channels.add();
channelRef.name = "Pixel Specs";
channelRef.kind = ChannelType.SELECTEDAREA;
}
docRef.selection.store(docRef.channels["Pixel Specs"], SelectionType.EXTEND);
var shapeRef = [
[fx1, fy1],
[fx2, fy1],
[fx2, fy2],
[fx1, fy2]
];
selRef.select(shapeRef, SelectionType.EXTEND);
selRef.load(docRef.channels["Pixel Specs"], SelectionType.DIMINISH);
channelRef.remove();
try {
var x1 = selRef.bounds[0].value;
var y1 = selRef.bounds[1].value;
var x2 = selRef.bounds[2].value;
var y2 = selRef.bounds[3].value;
} catch (error) {
// No selection bound - this means getting the inverse resulted in no selection,
// so assume negative shape did not exist (original selection was rectangle)
selRef.select(shapeRef);
is_rect = true;
x1 = fx1;
y1 = fy1;
x2 = fx2;
y2 = fy2;
}
rectInfo = getRectangles();
var inverseRectList = rectInfo.bounds;
docRef.selection.deselect();
// =======================================================
// Draw Labels
// =======================================================
var inner = {
'top': false,
'bottom': false,
'left': false,
'right': false
};
// Look for left measurement
if (fx1 < x1) {
inner.left = true;
if (fy1 == y1) createLabel(fx1, fy1 - 11, x1, fy1, true);
else if (fy2 == y2) createLabel(fx1, fy2, x1, fy2 + 10, true);
else createLabel(fx1, parseInt(fy1 + (fy2 - fy1) / 2) - 5, x1, parseInt(fy1 + (fy2 - fy1) / 2) + 5, true);
}
// Look for right measurement
if (fx2 > x2) {
if (!inner.left) inner.right = true;
if (fy1 == y1) createLabel(x2, fy1 - 11, fx2, fy1, true);
else if (fy2 == y2) createLabel(x2, fy2, fx2, fy2 + 10, true);
else createLabel(x2, parseInt(fy1 + (fy2 - fy1) / 2) - 5, fx2, parseInt(fy1 + (fy2 - fy1) / 2) + 5, true);
}
// Look for top measurement
if (fy1 < y1) {
inner.top = true;
if (fx1 == x1) createLabel(fx1 - 11, fy1, fx1, y1, false);
else if (fx2 == x2) createLabel(fx2, fy1, fx2 + 10, y1, false);
else createLabel(parseInt(fx1 + (fx2 - fx1) / 2) - 5, fy1, parseInt(fx1 + (fx2 - fx1) / 2) + 5, y1, false);
}
// Look for bottom measurement
if (fy2 > y2) {
if (!inner.top) inner.bottom = true;
if (fx1 == x1) createLabel(fx1 - 11, y2, fx1, fy2, false);
else if (fx2 == x2) createLabel(fx2, y2, fx2 + 10, fy2, false);
else createLabel(parseInt(fx1 + (fx2 - fx1) / 2) - 5, y2, parseInt(fx1 + (fx2 - fx1) / 2) + 5, fy2, false);
}
if (is_rect) {
// Only label the longest dimension when selection is a single rectangle
if (fx2 - fx1 > fy2 - fy1) createMultipleMeasures(true);
else createMultipleMeasures(false);
// Select containing folder (select was left on text layer, first item in folder)
if (activeDocument.activeLayer.parent.typename = "LayerSet") {
activeDocument.activeLayer = activeDocument.activeLayer.parent;
}
} else {
// Label both dimensions of negative space when it exists
if (inner.left) createLabel(x1, y1, x1 + 10, y2, false);
if (inner.right) createLabel(x2 - 11, y1, x2, y2, false);
if (inner.top) createLabel(x1, y1, x2, y1 + 10, true);
if (inner.bottom) createLabel(x1, y2 - 11, x2, y2, true);
if (!inner.left && !inner.right && !inner.top && !inner.bottom) {
if (inverseRectList.length == 4) {
// Horizontal bar: Q1.x2, Q1.y1, Q4.x1, Q4.y2
createLabel(inverseRectList[0][0], inverseRectList[0][3], inverseRectList[3][2], inverseRectList[3][1], true);
// Vertical bar: Q1.x1, Q1.y2, Q4.x2, Q4.y1
createLabel(inverseRectList[0][2], inverseRectList[0][1], inverseRectList[3][0], inverseRectList[3][3], false);
} else {
// Normal rectangle (no negative inner space)
createLabel(x1, y1, x2, y2, true);
createLabel(x1, y1, x2, y2, false);
}
}
}
app.preferences.rulerUnits = originalUnit;
}
function getRectangles() {
Array.prototype.numericSort = function () {
return this.sort(function (a, b) {
return a - b;
});
};
makeWorkPath(.4);
var tempPath = app.activeDocument.pathItems.getByName('Work Path');
var subPathCount = tempPath.subPathItems.length;
var subPathBounds = [];
var dirs = [];
for (sp = 0; sp < subPathCount; sp++) {
var b = [];
var xValues = [];
var yValues = [];
var pointCount = tempPath.subPathItems[sp].pathPoints.length;
var points = [];
for (var p = 0; p < pointCount; p++) {
xValues.push(tempPath.subPathItems[sp].pathPoints[p].anchor[0]);
yValues.push(tempPath.subPathItems[sp].pathPoints[p].anchor[1]);
// Pull off the last point (x,y) and add to the list
points.push([xValues[xValues.length - 1], yValues[yValues.length - 1]]);
}
xValues.numericSort();
yValues.numericSort();
var xMin = xValues[0];
var xMax = xValues[xValues.length - 1];
var yMin = yValues[0];
var yMax = yValues[yValues.length - 1];
subPathBounds.push([xMin, yMin, xMax, yMax]);
// Special case for 8 points - assume it's a rect with a cutout on one side. Cutout indicates
// we're in long side mode, and the label/line should be drawn on the opposing (to the cutout)
// side.
if (pointCount == 8) {
var lines = [];
var label;
for (var p = 0; p < points.length; p++) {
// Looking for a point that is along one side but not on a corner - that point is on the
// side opposite where the label will be drawn.
if ((points[p][0] == xMin || points[p][0] == xMax) && points[p][1] != yMin && points[p][1] != yMax) {
// Matching point is an x, so point is on a vertical side (either x1 or x2) and long lines are horizontal
lines.push([
[xMin, yMin],
[xMax - (use_fast_draw ? 0 : 1), yMin]
]);
lines.push([
[xMin, yMax - 1],
[xMax - (use_fast_draw ? 0 : 1), yMax - 1]
]);
if (points[p][0] == xMin) {
// Cut out is on the left line, so draw right line (inset for the arrow)
lines.push([
[xMax - arrow_size - 1, yMin],
[xMax - arrow_size - 1, yMax - 1]
]);
label = [xMax - 9, yMin];
} else {
// Cut out is on the right line, so draw left line (inset for the arrow)
lines.push([
[xMin + arrow_size, yMin],
[xMin + arrow_size, yMax - 1]
]);
if (yMax - yMin < 30) {
label = [xMin - 38, yMin];
} else {
label = [xMin - 2, yMin];
}
}
dirs.push({
'lines': lines,
'horizontal': false,
'label': label
});
break;
} else if ((points[p][1] == yMin || points[p][1] == yMax) && points[p][0] != xMin && points[p][0] != xMax) {
// Matching point is a y, so point is on a horizontal side (either y1 or y2) and long lines are vertical
lines.push([
[xMin, yMin],
[xMin, yMax - (use_fast_draw ? 0 : 1)]
]);
lines.push([
[xMax - 1, yMin],
[xMax - 1, yMax - (use_fast_draw ? 0 : 1)]
]);
if (points[p][1] == yMin) {
// Cut out is on the top line, so draw bottom line (inset for the arrow)
lines.push([
[xMin, yMax - arrow_size - 1],
[xMax - 1, yMax - arrow_size - 1]
]);
label = [xMin, yMax - 9];
} else {
// Cut out is on the bottom line, so draw top line (inset for the arrow)
lines.push([
[xMin, yMin + arrow_size],
[xMax - 1, yMin + arrow_size]
]);
// Get the top left for the "region" for the label - this is used to plug into the old createLabel()
// style when calling drawTextLabels()
if (xMax - xMin < 45) {
label = [xMin, yMin - 24];
} else {
label = [xMin, yMin - 2];
}
}
dirs.push({
'lines': lines,
'horizontal': true,
'label': label
});
break;
}
}
} else {
dirs.push(false);
}
}
tempPath.makeSelection(0);
tempPath.remove();
return {
'bounds': subPathBounds,
'longinfo': dirs
};
}
function createLongLabel(info) {
app.activeDocument.selection.deselect();
var linesLayerRef = layerSetRef.artLayers.add();
linesLayerRef.name = "Line ";
drawLine(info.lines[0][0], info.lines[0][1], 1); // long side
drawLine(info.lines[1][0], info.lines[1][1], 1); // long side
drawLine(info.lines[2][0], info.lines[2][1], 1); // label side
drawArrows(info.lines[2][0], info.lines[2][1], info.horizontal);
drawTextLabels(info.horizontal, info.horizontal ? info.lines[2][1][0] - info.lines[2][0][0] + 1 : info.lines[2][1][1] - info.lines[2][0][1] + 1, info.label[0], info.label[1])
}
function drawArrows(p1, p2, horizontal) {
if (!make_arrows) return true;
for (var i = 1; i <= arrow_size; i++) {
if (horizontal) {
drawLine([p1[0] + 1 + i, p1[1] - i], [p1[0] + 1 + i, p1[1] + i + (use_fast_draw ? 1 : 0)], 1);
drawLine([p2[0] - 1 - i, p1[1] - i], [p2[0] - 1 - i, p1[1] + i + (use_fast_draw ? 1 : 0)], 1);
} else {
drawLine([p1[0] - i, p1[1] + 1 + i], [p1[0] + i + (use_fast_draw ? 1 : 0), p1[1] + 1 + i], 1);
drawLine([p1[0] - i, p2[1] - 1 - i], [p1[0] + i + (use_fast_draw ? 1 : 0), p2[1] - 1 - i], 1);
}
}
}
function createLabel(x1, y1, x2, y2, horizontal) {
app.activeDocument.selection.deselect();
var linesLayerRef = layerSetRef.artLayers.add();
var width = x2 - x1;
var height = y2 - y1;
// =======================================================
// Draw Lines
// =======================================================
if (horizontal) {
linesLayerRef.name = "Line ";
drawLine([x1, y1], [x1, y1 + 10 + (use_fast_draw ? 1 : 0)], 1);
drawLine([x2 - 1, y1], [x2 - 1, y1 + 10 + (use_fast_draw ? 1 : 0)], 1);
drawLine([x1, y1 + 5], [x2 - 1, y1 + 5], 1);
if (make_arrows) {
for (var i = 1; i <= arrow_size; i++) {
drawLine([x1 + 1 + i, y1 + 5 - i], [x1 + 1 + i, y1 + 5 + i + (use_fast_draw ? 1 : 0)], 1);
drawLine([x2 - 2 - i, y1 + 5 - i], [x2 - 2 - i, y1 + 5 + i + (use_fast_draw ? 1 : 0)], 1);
}
}
} else {
linesLayerRef.name = "Line ";
drawLine([x1, y1], [x1 + 10 + (use_fast_draw ? 1 : 0), y1], 1);
drawLine([x1, y2 - 1], [x1 + 10 + (use_fast_draw ? 1 : 0), y2 - 1], 1);
drawLine([x1 + 5, y1], [x1 + 5, y2 - 1], 1);
if (make_arrows) {
for (var i = 1; i <= arrow_size; i++) {
drawLine([x1 + 5 - i, y1 + 1 + i], [x1 + 5 + i + (use_fast_draw ? 1 : 0), y1 + 1 + i], 1);
drawLine([x1 + 5 - i, y2 - 2 - i], [x1 + 5 + i + (use_fast_draw ? 1 : 0), y2 - 2 - i], 1);
}
}
}
drawTextLabels(horizontal, horizontal ? width : height, x1, y1);
}
function drawTextLabels(horizontal, size, x, y) {
// =======================================================
// Draw Text
// =======================================================
var textLayerRef = layerSetRef.artLayers.add();
textLayerRef.kind = LayerKind.TEXT;
var textItemRef = textLayerRef.textItem;
if (rectangleList.length == 1) {
textItemRef.contents = size + "px";
layerSetRef.name = textItemRef.contents;
}
if (horizontal) {
if (size < 45 || !make_centered_labels) {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.justification = Justification.CENTER;
textItemRef.position = Array(Math.floor(x + (size / 2)), y + 20);
textItemRef.contents = size + "px";
} else {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.justification = Justification.CENTER;
textItemRef.position = Array(Math.floor(x + (size / 2)), y + 8);
textItemRef.contents = size + "px";
loadTransparency();
app.activeDocument.selection.expand(4);
selectLayerBelow();
app.activeDocument.selection.cut();
}
} else {
if (size < 30 || !make_centered_labels) {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.position = Array(x + 12, Math.floor(y + 4 + (size / 2)));
textItemRef.contents = size + "px";
} else {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.justification = Justification.CENTER;
textItemRef.position = Array(x + 5, Math.floor(y + 4 + (size / 2)));
textItemRef.contents = size + "px";
loadTransparency();
app.activeDocument.selection.expand(4);
selectLayerBelow();
app.activeDocument.selection.cut();
}
}
}
function makeWorkPath(tolerance) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putClass(charIDToTypeID('Path'));
desc.putReference(charIDToTypeID('null'), ref);
var ref2 = new ActionReference();
ref2.putProperty(charIDToTypeID('csel'), charIDToTypeID('fsel'));
desc.putReference(charIDToTypeID('From'), ref2);
desc.putUnitDouble(charIDToTypeID('Tlrn'), charIDToTypeID('#Pxl'), tolerance);
executeAction(charIDToTypeID('Mk '), desc, DialogModes.NO);
}
function makeSelectionF() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty(charIDToTypeID('Chnl'), charIDToTypeID('fsel'));
desc.putReference(charIDToTypeID('null'), ref);
var ref = new ActionReference();
ref.putProperty(charIDToTypeID('Path'), charIDToTypeID('WrPt'));
desc.putReference(charIDToTypeID('T '), ref);
desc.putInteger(charIDToTypeID('Vrsn'), 1);
desc.putBoolean(stringIDToTypeID('vectorMaskParams'), true);
executeAction(charIDToTypeID('setd'), desc, DialogModes.NO);
};
function drawLine_slower(x1, y1, x2, y2) {
var pointArray = new Array();
var pointA = new PathPointInfo();
pointA.kind = PointKind.CORNERPOINT;
pointA.anchor = Array(x1, y1);
pointA.leftDirection = pointA.anchor;
pointA.rightDirection = pointA.anchor;
pointArray.push(pointA);
var pointB = new PathPointInfo();
pointB.kind = PointKind.CORNERPOINT;
pointB.anchor = Array(x2, y2);
pointB.leftDirection = pointB.anchor;
pointB.rightDirection = pointB.anchor;
pointArray.push(pointB);
var line = new SubPathInfo();
line.operation = ShapeOperation.SHAPEXOR;
line.closed = false;
line.entireSubPath = pointArray;
var lineSubPathArray = new Array();
lineSubPathArray.push(line);
var linePath = app.activeDocument.pathItems.add("TempPath", lineSubPathArray);
linePath.strokePath(ToolType.PENCIL, false);
app.activeDocument.pathItems.removeAll();
};
function drawLine(startXY, endXY, width) {
if (!use_fast_draw) return drawLine_slower(startXY[0], startXY[1], endXY[0], endXY[1]);
var desc = new ActionDescriptor();
var lineDesc = new ActionDescriptor();
var startDesc = new ActionDescriptor();
startDesc.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), startXY[0]);
startDesc.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), startXY[1]);
lineDesc.putObject(charIDToTypeID('Strt'), charIDToTypeID('Pnt '), startDesc);
var endDesc = new ActionDescriptor();
endDesc.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), endXY[0]);
endDesc.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), endXY[1]);
lineDesc.putObject(charIDToTypeID('End '), charIDToTypeID('Pnt '), endDesc);
lineDesc.putUnitDouble(charIDToTypeID('Wdth'), charIDToTypeID('#Pxl'), width);
desc.putObject(charIDToTypeID('Shp '), charIDToTypeID('Ln '), lineDesc);
desc.putBoolean(charIDToTypeID('AntA'), false);
executeAction(charIDToTypeID('Draw'), desc, DialogModes.NO);
};
function hasSelection(doc) {
var res = false;
var as = doc.activeHistoryState;
doc.selection.deselect();
if (as != doc.activeHistoryState) {
res = true;
doc.activeHistoryState = as;
}
return res;
}
function selectLayerBelow() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Bckw"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putBoolean(charIDToTypeID("MkVs"), false);
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};
function selectLayerAbove() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Frwr"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putBoolean(charIDToTypeID("MkVs"), false);
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};
function loadTransparency(Invert) {
if (Invert == undefined) Invert = false;
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Chnl"), charIDToTypeID("fsel"));
desc.putReference(charIDToTypeID("null"), ref);
var ref1 = new ActionReference();
ref1.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Trsp"));
desc.putReference(charIDToTypeID("T "), ref1);
desc.putBoolean(charIDToTypeID('Invr'), Invert);
executeAction(charIDToTypeID("setd"), desc, DialogModes.NO);
};
function selectLayerByIndex(index, add) {
add = (add == undefined) ? add = false : add;
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
};
function getActiveLayerIndex() {
var ref = new ActionReference();
ref.putProperty(1349677170, 1232366921);
ref.putEnumerated(1283027488, 1332896878, 1416783732);
try {
activeDocument.backgroundLayer;
var res = executeActionGet(ref)
.getInteger(1232366921) - 1;
} catch (e) {
var res = executeActionGet(ref)
.getInteger(1232366921);
}
return res;
};
function linkSelectedLayers() {
var desc221 = new ActionDescriptor();
var ref142 = new ActionReference();
ref142.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc221.putReference(charIDToTypeID('null'), ref142);
executeAction(stringIDToTypeID('linkSelectedLayers'), desc221, DialogModes.NO);
};
function loadVectorMask() {
// =======================================================
var idsetd = charIDToTypeID("setd");
var desc14 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref9 = new ActionReference();
var idChnl = charIDToTypeID("Chnl");
var idfsel = charIDToTypeID("fsel");
ref9.putProperty(idChnl, idfsel);
desc14.putReference(idnull, ref9);
var idT = charIDToTypeID("T ");
var ref10 = new ActionReference();
var idPath = charIDToTypeID("Path");
var idPath = charIDToTypeID("Path");
var idvectorMask = stringIDToTypeID("vectorMask");
ref10.putEnumerated(idPath, idPath, idvectorMask);
var idLyr = charIDToTypeID("Lyr ");
var idOrdn = charIDToTypeID("Ordn");
var idTrgt = charIDToTypeID("Trgt");
ref10.putEnumerated(idLyr, idOrdn, idTrgt);
desc14.putReference(idT, ref10);
var idVrsn = charIDToTypeID("Vrsn");
desc14.putInteger(idVrsn, 1);
var idvectorMaskParams = stringIDToTypeID("vectorMaskParams");
desc14.putBoolean(idvectorMaskParams, true);
executeAction(idsetd, desc14, DialogModes.NO);
};
function loadLayerMask() {
// =======================================================
var idsetd = charIDToTypeID("setd");
var desc21 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref14 = new ActionReference();
var idChnl = charIDToTypeID("Chnl");
var idfsel = charIDToTypeID("fsel");
ref14.putProperty(idChnl, idfsel);
desc21.putReference(idnull, ref14);
var idT = charIDToTypeID("T ");
var ref15 = new ActionReference();
var idChnl = charIDToTypeID("Chnl");
var idChnl = charIDToTypeID("Chnl");
var idMsk = charIDToTypeID("Msk ");
ref15.putEnumerated(idChnl, idChnl, idMsk);
desc21.putReference(idT, ref15);
executeAction(idsetd, desc21, DialogModes.NO);
};
///////////////////////////////////////////////////////////////////////////////
// Function: hasVectorMask
// Usage: see if there is a vector layer mask
// Input: <none> Must have an open document
// Return: true if there is a vector mask
///////////////////////////////////////////////////////////////////////////////
function hasVectorMask() {
var hasVectorMask = false;
try {
var ref = new ActionReference();
var keyVectorMaskEnabled = app.stringIDToTypeID('vectorMask');
var keyKind = app.charIDToTypeID('Knd ');
ref.putEnumerated(app.charIDToTypeID('Path'), app.charIDToTypeID('Ordn'), keyVectorMaskEnabled);
var desc = executeActionGet(ref);
if (desc.hasKey(keyKind)) {
var kindValue = desc.getEnumerationValue(keyKind);
if (kindValue == keyVectorMaskEnabled) {
hasVectorMask = true;
}
}
} catch (e) {
hasVectorMask = false;
}
return hasVectorMask;
};
function multiselectfontreader() {
// by paul riggott; MULTI-SELECT Function
app.bringToFront();
main();
function main() {
if (!documents.length) return;
var selLayers = [];
selLayers = getSelectedLayersIdx();
for (var a in selLayers) {
makeActiveByIndex(selLayers[a], false);
//amend to suit.
readTextLayer()
}
}
function getSelectedLayersIdx() {
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID('targetLayers'))) {
desc = desc.getList(stringIDToTypeID('targetLayers'));
var c = desc.count
var selectedLayers = new Array();
for (var i = 0; i < c; i++) {
try {
activeDocument.backgroundLayer;
selectedLayers.push(desc.getReference(i)
.getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i)
.getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Prpr"), charIDToTypeID("ItmI"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
try {
activeDocument.backgroundLayer;
selectedLayers.push(executeActionGet(ref)
.getInteger(charIDToTypeID("ItmI")) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref)
.getInteger(charIDToTypeID("ItmI")));
}
}
return selectedLayers;
};
function makeActiveByIndex(idx, visible) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), idx)
desc.putReference(charIDToTypeID("null"), ref);
desc.putBoolean(charIDToTypeID("MkVs"), visible);
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};
};
// Read one or more selected fonts
function readTextLayer() {
if (app.documents.length > 0) {
var myDoc = app.activeDocument;
var myLayer = myDoc.activeLayer;
if (myLayer.kind == LayerKind.TEXT) {
var thisText = myLayer.textItem;
// Renaming the Justifcation info from Justification.CENTER - > Center;
try {
var theJustification = String(thisText.justification)
.replace("Justification.", "")
} catch (e) {
var theJustification = "LEFT"
};
theJustification = theJustification[0] + theJustification.slice(1, theJustification.length)
.toLowerCase();
var fonts = getFonts(app.activeDocument.activeLayer);
for (var i = 0; i < fonts.length; i++) {
addTextLayer(
((fonts.length > 1) ? fonts[i].text + ((fonts[i].text.length) ? "\r" : '') : '') + "Font: " + fonts[i].font + "\r" + "Size: " + fonts[i].size + "\r" + "Color: #" + fonts[i].color.rgb.hexValue + "\r" + ((i === 0 && fonts[i].leading !== '' && TextLeading == true) ? "Leading: " + fonts[i].leading + "\r" : '') + ((i === 0 && TextJustification == true) ? "Justify: " + theJustification + "\r" : ''),
"Font Info #" + (i + 1),
[myLayer.bounds[0] + i * 150, myLayer.bounds[3] + 15]
//Code for dynamically figuring out width hieght canvas size and placing the text objects accordingly//
/*
(myDoc.width > myDoc.height?[myLayer.bounds[0] + i * 150, myLayer.bounds[3] + 15]:[myLayer.bounds[0], myLayer.bounds[3] + i * 100])
*/
);
}
}
}
};
// Add's a text layer which contains the content of the read string above
function addTextLayer(theText, theName, thePosition) {
var aTextLayer = app.activeDocument.artLayers.add();
aTextLayer.kind = LayerKind.TEXT;
aTextLayer.name = theName;
var aTextLayerRef = aTextLayer.textItem;
aTextLayerRef.kind = TextType.POINTTEXT;
aTextLayerRef.size = 10;
aTextLayerRef.font = "Arial-BoldMT";
aTextLayerRef.color = app.foregroundColor;
aTextLayerRef.justification = Justification.LEFT;
aTextLayerRef.position = thePosition;
aTextLayer.blendMode = BlendMode.NORMAL;
aTextLayer.opacity = 100;
aTextLayer.fillOpacity = 100;
aTextLayerRef.useAutoLeading = true;
aTextLayerRef.leading = 0;
aTextLayerRef.horizontalScale = 100;
aTextLayerRef.verticalScale = 100;
aTextLayerRef.contents = theText;
aTextLayerRef.antiAliasMethod = AntiAlias.SHARP;
//Move the newly created font layers into the existing "Pixel Spec" folder
var doc = app.activeDocument;
var srcLayer = doc.activeLayer;
try {
moveLayerToSet(doc, srcLayer, 'Pixel Specs');
} catch (error) {
false;
}
function moveLayerToSet(doc, srcLayer, toLayerName) {
var destLayer = doc.layers[toLayerName];
if (destLayer.layers) destLayer = destLayer.layers[0];
srcLayer.move(destLayer, ElementPlacement.PLACEBEFORE);
}
};
function getColorFromDescriptor(colorDesc, keyClass) {
var colorObject = new SolidColor();
switch (keyClass) {
case "Grsc":
colorObject.grey.grey = color.getDouble(charIDToTypeID('Gry '));
break;
case "RGBC":
colorObject.rgb.red = colorDesc.getDouble(charIDToTypeID('Rd '));
colorObject.rgb.green = colorDesc.getDouble(charIDToTypeID('Grn '));
colorObject.rgb.blue = colorDesc.getDouble(charIDToTypeID('Bl '));
break;
case "CMYC":
colorObject.cmyk.cyan = colorDesc.getDouble(charIDToTypeID('Cyn '));
colorObject.cmyk.magenta = colorDesc.getDouble(charIDToTypeID('Mgnt'));
colorObject.cmyk.yellow = colorDesc.getDouble(charIDToTypeID('Ylw '));
colorObject.cmyk.black = colorDesc.getDouble(charIDToTypeID('Blck'));
break;
case "LbCl":
colorObject.lab.l = colorDesc.getDouble(charIDToTypeID('Lmnc'));
colorObject.lab.a = colorDesc.getDouble(charIDToTypeID('A '));
colorObject.lab.b = colorDesc.getDouble(charIDToTypeID('B '));
break;
default:
return null;
}
return colorObject;
};
// get fonts and other parameters used in type layer
function getFonts(textLayer) {
function markReturnedContentText(text) {
if (font_content_detection) {
return font_content_detection_symbols[0] + text + font_content_detection_symbols[1] + "\r";
} else {
return '';
}
}
if (textLayer.kind == LayerKind.TEXT) {
app.activeDocument.activeLayer = textLayer;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDesc = executeActionGet(ref);
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var rangeList = textDesc.getList(stringIDToTypeID('textStyleRange'));
var fonts = [];
for (var m = 0; m < rangeList.count; m++) {
var styleDesc = rangeList.getObjectValue(m)
.getObjectValue(stringIDToTypeID('textStyle'));
var aFrom = rangeList.getObjectValue(m)
.getInteger(stringIDToTypeID('from'));
var aTo = rangeList.getObjectValue(m)
.getInteger(stringIDToTypeID('to'));
if (m > 0) {
if (rangeList.getObjectValue(m - 1)
.getInteger(stringIDToTypeID('from')) == aFrom && rangeList.getObjectValue(m - 1)
.getInteger(stringIDToTypeID('to')) == aTo) continue;
}
var theLetters = app.activeDocument.activeLayer.textItem.contents.substring(aFrom, aTo);
var aFont = styleDesc.getString(stringIDToTypeID('fontPostScriptName'));
//var aSize = styleDesc.getUnitDoubleValue(stringIDToTypeID('size')) + " " + typeIDToCharID(styleDesc.getUnitDoubleType(stringIDToTypeID('size')));
var aSize = new UnitValue(styleDesc.getUnitDoubleValue(stringIDToTypeID('size')), "px");
//Check if font has been transformed
if (textDesc.hasKey(stringIDToTypeID('transform'))) {
var mFactor = textDesc.getObjectValue(stringIDToTypeID('transform')).getUnitDoubleValue (stringIDToTypeID("yy") );
aSize = Math.round(aSize * mFactor);
}
var aColor = getColorFromDescriptor(styleDesc.getObjectValue(charIDToTypeID("Clr ")), typeIDToCharID(styleDesc.getClass(charIDToTypeID("Clr "))));
if (styleDesc.hasKey(stringIDToTypeID('leading'))) {
var aLeading = new UnitValue(styleDesc.getUnitDoubleValue(stringIDToTypeID('leading')), "px");
} else {
var aLeading = "";
}
var txt = theLetters.replace(/^\s+/, '').replace(/\s+$/, '');
var merged = false;
if (txt.length > 0) {
for (var x = 0; x < m; x++) {
try {
if (fonts[x].font === aFont && fonts[x].size === aSize && fonts[x].color.rgb.hexValue === aColor.rgb.hexValue && fonts[x].leading === aLeading) {
// It's a hack!!!
if (fonts[x].text !== txt) {
fonts[x].text += markReturnedContentText(txt);
}
merged = true;
}
} catch (e) {}
}
if (!merged) {
fonts.push({
text: markReturnedContentText(txt),
font: aFont,
size: aSize,
color: aColor,
leading: aLeading
});
}
}
};
return fonts;
}
};
On a slightly different but similar topic, remember the text splitter script I posted earlier regarding having the ability to combine....but you noted it can be done it's just that you will lose any other text styles(font type, size, color...etc) once it does split/combine. Since you made a break through in reading several different type fonts on one line in my Pixel Measure Script, is it possible to somehow implement this code into this text split/combine script now?
Here's the Text Splitter Code:
Code: Select alldoc = app.activeDocument;
layer = doc.activeLayer;
var text = layer.textItem.contents;
var textArray = text.split("\r");
var pos = layer.textItem.position;
var leading = 0;
if (layer.textItem.useAutoLeading){
leading = layer.textItem.size/100*Math.round(layer.textItem.autoLeadingAmount)
}
else{
leading = Number(layer.textItem.leading)
}
layer.textItem.contents=textArray[0]
layer.name = textArray[0]
for (var k=1; k<textArray.length;k++){
tmp = layer.duplicate();
tmp.textItem.position = [pos[0], pos[1]+(Number(leading)*k)]
tmp.textItem.contents = textArray[k];
}
Pixel Measure Spec Script with Font Reader at the bottom:
Code: Select all /*
DISCLAIMER / TERMS & CONDITIONS / CREDITS
---------------------------------------------------------------------------------------------------------------------------------------------------
Pixel Measure v0.04 - Photoshop script for adding pixel measurements to your mockups
Copyright (C) 2009 Nikolaj Selvik
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
---------------------------------------------------------------------------------------------------------------------------------------------------
Updated by Bezzy Weitz (Magical Coder - a million thx for his time) & Mycort (GUI Artist & Idea Man)
Creators of functions 3 -> 7 (4/15/2012 - v0.05). Specifc code edits and additions include:
- 4 measures using "L"shaped selection
- 2 measures using crosshair selections
- 6 measures of inner/outer box
- Simultaneous Measure (Vert & Horiz -All at once)
- Arrow edge drawing (toggle function)
- Adding "var" section for easier editing of toggled functions
- Long extended edge line (8 point Detection Function)
Code snippets and advice help courtesy of (bb/)
- Working code for converting selection to paths to detect values of simultaneous measures
- Centering of labels/cut line
- Making the code faster with the addition of Script Listener
- In multiple measures mode, new function to link both lines/label together for easier movement
- Font analyzer, creation of text layer info, multiple selection
Font-detection system updated by Maksim Izmaylov <me@kvakes.com> in 2012.
==========================================================================================
Got questions or suggestions for further improvement?
- Contact me at: mycort@yahoo.com
- A little plug for my portfolio site: mycort.deviantart.com/gallery
==========================================================================================
Great many thanks to Nikolaj Selvik, the developer who first and initially created this time saving tool.
- Original creator of functions 1 & 2 (Horizontal & vertical "single" selection)
- Uncentered Label
- Line edge drawing
---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#target photoshop
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Toggle functions (put true or false here to turn on/off features)
var make_arrows = true;
var make_centered_labels = true;
var make_bold_labels = true;
var use_fast_draw = false;
var LinkLayers = false;
var font_size = 10;
var arrow_size = 3;
var font_content_detection = true;
var font_content_detection_symbols = ['(', ')'];
var TextLeading =true;
var TextJustification =true;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var mainLayerSet;
var layerSetRef;
var rectInfo;
var rectangleList;
var originalUnit = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var myDocument = app.activeDocument;
var theLayer = myDocument.activeLayer;
var myDoc = app.activeDocument;
var myLayer = myDoc.activeLayer;
var origResolution = myDocument.resolution;
myDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);
app.displayDialogs = DialogModes.NO;
if (validateState()) {
app.activeDocument.suspendHistory("Pixel Specs", "pm();");
};
myDocument.resolution = origResolution;
function pm() {
// =======================================================
// Create Layer Sets
// =======================================================
try {
mainLayerSet = app.activeDocument.layerSets.getByName("Pixel Specs");
} catch (error) {
mainLayerSet = app.activeDocument.layerSets.add();
mainLayerSet.name = "Pixel Specs";
}
layerSetRef = mainLayerSet.layerSets.add();
// Determine how many independent rectangles exist in the selection
rectInfo = getRectangles();
rectangleList = rectInfo.bounds;
if (rectangleList.length == 2 && (is_inside(rectangleList[0], rectangleList[1]) || is_inside(rectangleList[1], rectangleList[0]))) createMeasure();
else if (rectangleList.length == 1) {
if (rectInfo.longinfo[0] === false) createMeasure();
else createLongLabel(rectInfo.longinfo[0]);
} else if (rectangleList.length > 1) createMultipleMeasures();
app.activeDocument.selection.deselect();
if (rectangleList.length > 1) {
layerSetRef.name = "Multiple Measures";
}
}
// Linking function of multiple measures
if (LinkLayers) {
if (activeDocument.activeLayer.typename != "LayerSet") {
if (activeDocument.activeLayer.parent.typename = "LayerSet") {
activeDocument.activeLayer = activeDocument.activeLayer.parent;
}
if (rectangleList.length > 1) {
var doc = activeDocument;
var thisSet = doc.activeLayer;
var LayerList = new Array();
for (var a = 0; a < thisSet.layers.length; a++) {
activeDocument.activeLayer = thisSet.layers[a];
LayerList.push(getActiveLayerIndex());
}
while (LayerList.length > 0) {
selectLayerByIndex(Number(LayerList.shift()));
selectLayerByIndex(Number(LayerList.shift()), true);
linkSelectedLayers();
}
}
}
}
function validateState() {
if (app.documents.length == 0) {
alert("No document open");
return false;
}
if (!hasSelection(app.activeDocument)) {
if (myLayer.kind == LayerKind.TEXT) {
multiselectfontreader();
return false
} else {
loadTransparency()
}
}
return true;
}
function is_inside(r1, r2) {
return r1[0] <= r2[0] && r1[1] <= r2[1] && r1[2] >= r2[2] && r1[3] >= r2[3];
}
function createMultipleMeasures() {
for (var i = 0; i < rectangleList.length; i++) {
if (rectInfo.longinfo === false) {
if (rectangleList[2] - rectangleList[0] > rectangleList[3] - rectangleList[1]) createLabel(rectangleList[0], parseInt(rectangleList[1] + (rectangleList[3] - rectangleList[1]) / 2) - 5, rectangleList[2], parseInt(rectangleList[i][1] + (rectangleList[i][3] - rectangleList[i][1]) / 2) + 5, true);
else createLabel(parseInt(rectangleList[i][0] + (rectangleList[i][2] - rectangleList[i][0]) / 2) - 5, rectangleList[i][1], parseInt(rectangleList[i][0] + (rectangleList[i][2] - rectangleList[i][0]) / 2) + 5, rectangleList[i][3], false);
} else {
createLongLabel(rectInfo.longinfo[i]);
}
}
}
function createMeasure() {
var docRef = app.activeDocument;
var selRef = docRef.selection;
var channelRef;
var is_rect = false;
// =======================================================
// Set Up Selection
// =======================================================
var fx1 = selRef.bounds[0].value;
var fy1 = selRef.bounds[1].value;
var fx2 = selRef.bounds[2].value;
var fy2 = selRef.bounds[3].value;
try {
channelRef = docRef.channels.getByName("Pixel Specs");
} catch (error) {
channelRef = docRef.channels.add();
channelRef.name = "Pixel Specs";
channelRef.kind = ChannelType.SELECTEDAREA;
}
docRef.selection.store(docRef.channels["Pixel Specs"], SelectionType.EXTEND);
var shapeRef = [
[fx1, fy1],
[fx2, fy1],
[fx2, fy2],
[fx1, fy2]
];
selRef.select(shapeRef, SelectionType.EXTEND);
selRef.load(docRef.channels["Pixel Specs"], SelectionType.DIMINISH);
channelRef.remove();
try {
var x1 = selRef.bounds[0].value;
var y1 = selRef.bounds[1].value;
var x2 = selRef.bounds[2].value;
var y2 = selRef.bounds[3].value;
} catch (error) {
// No selection bound - this means getting the inverse resulted in no selection,
// so assume negative shape did not exist (original selection was rectangle)
selRef.select(shapeRef);
is_rect = true;
x1 = fx1;
y1 = fy1;
x2 = fx2;
y2 = fy2;
}
rectInfo = getRectangles();
var inverseRectList = rectInfo.bounds;
docRef.selection.deselect();
// =======================================================
// Draw Labels
// =======================================================
var inner = {
'top': false,
'bottom': false,
'left': false,
'right': false
};
// Look for left measurement
if (fx1 < x1) {
inner.left = true;
if (fy1 == y1) createLabel(fx1, fy1 - 11, x1, fy1, true);
else if (fy2 == y2) createLabel(fx1, fy2, x1, fy2 + 10, true);
else createLabel(fx1, parseInt(fy1 + (fy2 - fy1) / 2) - 5, x1, parseInt(fy1 + (fy2 - fy1) / 2) + 5, true);
}
// Look for right measurement
if (fx2 > x2) {
if (!inner.left) inner.right = true;
if (fy1 == y1) createLabel(x2, fy1 - 11, fx2, fy1, true);
else if (fy2 == y2) createLabel(x2, fy2, fx2, fy2 + 10, true);
else createLabel(x2, parseInt(fy1 + (fy2 - fy1) / 2) - 5, fx2, parseInt(fy1 + (fy2 - fy1) / 2) + 5, true);
}
// Look for top measurement
if (fy1 < y1) {
inner.top = true;
if (fx1 == x1) createLabel(fx1 - 11, fy1, fx1, y1, false);
else if (fx2 == x2) createLabel(fx2, fy1, fx2 + 10, y1, false);
else createLabel(parseInt(fx1 + (fx2 - fx1) / 2) - 5, fy1, parseInt(fx1 + (fx2 - fx1) / 2) + 5, y1, false);
}
// Look for bottom measurement
if (fy2 > y2) {
if (!inner.top) inner.bottom = true;
if (fx1 == x1) createLabel(fx1 - 11, y2, fx1, fy2, false);
else if (fx2 == x2) createLabel(fx2, y2, fx2 + 10, fy2, false);
else createLabel(parseInt(fx1 + (fx2 - fx1) / 2) - 5, y2, parseInt(fx1 + (fx2 - fx1) / 2) + 5, fy2, false);
}
if (is_rect) {
// Only label the longest dimension when selection is a single rectangle
if (fx2 - fx1 > fy2 - fy1) createMultipleMeasures(true);
else createMultipleMeasures(false);
// Select containing folder (select was left on text layer, first item in folder)
if (activeDocument.activeLayer.parent.typename = "LayerSet") {
activeDocument.activeLayer = activeDocument.activeLayer.parent;
}
} else {
// Label both dimensions of negative space when it exists
if (inner.left) createLabel(x1, y1, x1 + 10, y2, false);
if (inner.right) createLabel(x2 - 11, y1, x2, y2, false);
if (inner.top) createLabel(x1, y1, x2, y1 + 10, true);
if (inner.bottom) createLabel(x1, y2 - 11, x2, y2, true);
if (!inner.left && !inner.right && !inner.top && !inner.bottom) {
if (inverseRectList.length == 4) {
// Horizontal bar: Q1.x2, Q1.y1, Q4.x1, Q4.y2
createLabel(inverseRectList[0][0], inverseRectList[0][3], inverseRectList[3][2], inverseRectList[3][1], true);
// Vertical bar: Q1.x1, Q1.y2, Q4.x2, Q4.y1
createLabel(inverseRectList[0][2], inverseRectList[0][1], inverseRectList[3][0], inverseRectList[3][3], false);
} else {
// Normal rectangle (no negative inner space)
createLabel(x1, y1, x2, y2, true);
createLabel(x1, y1, x2, y2, false);
}
}
}
app.preferences.rulerUnits = originalUnit;
}
function getRectangles() {
Array.prototype.numericSort = function () {
return this.sort(function (a, b) {
return a - b;
});
};
makeWorkPath(.4);
var tempPath = app.activeDocument.pathItems.getByName('Work Path');
var subPathCount = tempPath.subPathItems.length;
var subPathBounds = [];
var dirs = [];
for (sp = 0; sp < subPathCount; sp++) {
var b = [];
var xValues = [];
var yValues = [];
var pointCount = tempPath.subPathItems[sp].pathPoints.length;
var points = [];
for (var p = 0; p < pointCount; p++) {
xValues.push(tempPath.subPathItems[sp].pathPoints[p].anchor[0]);
yValues.push(tempPath.subPathItems[sp].pathPoints[p].anchor[1]);
// Pull off the last point (x,y) and add to the list
points.push([xValues[xValues.length - 1], yValues[yValues.length - 1]]);
}
xValues.numericSort();
yValues.numericSort();
var xMin = xValues[0];
var xMax = xValues[xValues.length - 1];
var yMin = yValues[0];
var yMax = yValues[yValues.length - 1];
subPathBounds.push([xMin, yMin, xMax, yMax]);
// Special case for 8 points - assume it's a rect with a cutout on one side. Cutout indicates
// we're in long side mode, and the label/line should be drawn on the opposing (to the cutout)
// side.
if (pointCount == 8) {
var lines = [];
var label;
for (var p = 0; p < points.length; p++) {
// Looking for a point that is along one side but not on a corner - that point is on the
// side opposite where the label will be drawn.
if ((points[p][0] == xMin || points[p][0] == xMax) && points[p][1] != yMin && points[p][1] != yMax) {
// Matching point is an x, so point is on a vertical side (either x1 or x2) and long lines are horizontal
lines.push([
[xMin, yMin],
[xMax - (use_fast_draw ? 0 : 1), yMin]
]);
lines.push([
[xMin, yMax - 1],
[xMax - (use_fast_draw ? 0 : 1), yMax - 1]
]);
if (points[p][0] == xMin) {
// Cut out is on the left line, so draw right line (inset for the arrow)
lines.push([
[xMax - arrow_size - 1, yMin],
[xMax - arrow_size - 1, yMax - 1]
]);
label = [xMax - 9, yMin];
} else {
// Cut out is on the right line, so draw left line (inset for the arrow)
lines.push([
[xMin + arrow_size, yMin],
[xMin + arrow_size, yMax - 1]
]);
if (yMax - yMin < 30) {
label = [xMin - 38, yMin];
} else {
label = [xMin - 2, yMin];
}
}
dirs.push({
'lines': lines,
'horizontal': false,
'label': label
});
break;
} else if ((points[p][1] == yMin || points[p][1] == yMax) && points[p][0] != xMin && points[p][0] != xMax) {
// Matching point is a y, so point is on a horizontal side (either y1 or y2) and long lines are vertical
lines.push([
[xMin, yMin],
[xMin, yMax - (use_fast_draw ? 0 : 1)]
]);
lines.push([
[xMax - 1, yMin],
[xMax - 1, yMax - (use_fast_draw ? 0 : 1)]
]);
if (points[p][1] == yMin) {
// Cut out is on the top line, so draw bottom line (inset for the arrow)
lines.push([
[xMin, yMax - arrow_size - 1],
[xMax - 1, yMax - arrow_size - 1]
]);
label = [xMin, yMax - 9];
} else {
// Cut out is on the bottom line, so draw top line (inset for the arrow)
lines.push([
[xMin, yMin + arrow_size],
[xMax - 1, yMin + arrow_size]
]);
// Get the top left for the "region" for the label - this is used to plug into the old createLabel()
// style when calling drawTextLabels()
if (xMax - xMin < 45) {
label = [xMin, yMin - 24];
} else {
label = [xMin, yMin - 2];
}
}
dirs.push({
'lines': lines,
'horizontal': true,
'label': label
});
break;
}
}
} else {
dirs.push(false);
}
}
tempPath.makeSelection(0);
tempPath.remove();
return {
'bounds': subPathBounds,
'longinfo': dirs
};
}
function createLongLabel(info) {
app.activeDocument.selection.deselect();
var linesLayerRef = layerSetRef.artLayers.add();
linesLayerRef.name = "Line ";
drawLine(info.lines[0][0], info.lines[0][1], 1); // long side
drawLine(info.lines[1][0], info.lines[1][1], 1); // long side
drawLine(info.lines[2][0], info.lines[2][1], 1); // label side
drawArrows(info.lines[2][0], info.lines[2][1], info.horizontal);
drawTextLabels(info.horizontal, info.horizontal ? info.lines[2][1][0] - info.lines[2][0][0] + 1 : info.lines[2][1][1] - info.lines[2][0][1] + 1, info.label[0], info.label[1])
}
function drawArrows(p1, p2, horizontal) {
if (!make_arrows) return true;
for (var i = 1; i <= arrow_size; i++) {
if (horizontal) {
drawLine([p1[0] + 1 + i, p1[1] - i], [p1[0] + 1 + i, p1[1] + i + (use_fast_draw ? 1 : 0)], 1);
drawLine([p2[0] - 1 - i, p1[1] - i], [p2[0] - 1 - i, p1[1] + i + (use_fast_draw ? 1 : 0)], 1);
} else {
drawLine([p1[0] - i, p1[1] + 1 + i], [p1[0] + i + (use_fast_draw ? 1 : 0), p1[1] + 1 + i], 1);
drawLine([p1[0] - i, p2[1] - 1 - i], [p1[0] + i + (use_fast_draw ? 1 : 0), p2[1] - 1 - i], 1);
}
}
}
function createLabel(x1, y1, x2, y2, horizontal) {
app.activeDocument.selection.deselect();
var linesLayerRef = layerSetRef.artLayers.add();
var width = x2 - x1;
var height = y2 - y1;
// =======================================================
// Draw Lines
// =======================================================
if (horizontal) {
linesLayerRef.name = "Line ";
drawLine([x1, y1], [x1, y1 + 10 + (use_fast_draw ? 1 : 0)], 1);
drawLine([x2 - 1, y1], [x2 - 1, y1 + 10 + (use_fast_draw ? 1 : 0)], 1);
drawLine([x1, y1 + 5], [x2 - 1, y1 + 5], 1);
if (make_arrows) {
for (var i = 1; i <= arrow_size; i++) {
drawLine([x1 + 1 + i, y1 + 5 - i], [x1 + 1 + i, y1 + 5 + i + (use_fast_draw ? 1 : 0)], 1);
drawLine([x2 - 2 - i, y1 + 5 - i], [x2 - 2 - i, y1 + 5 + i + (use_fast_draw ? 1 : 0)], 1);
}
}
} else {
linesLayerRef.name = "Line ";
drawLine([x1, y1], [x1 + 10 + (use_fast_draw ? 1 : 0), y1], 1);
drawLine([x1, y2 - 1], [x1 + 10 + (use_fast_draw ? 1 : 0), y2 - 1], 1);
drawLine([x1 + 5, y1], [x1 + 5, y2 - 1], 1);
if (make_arrows) {
for (var i = 1; i <= arrow_size; i++) {
drawLine([x1 + 5 - i, y1 + 1 + i], [x1 + 5 + i + (use_fast_draw ? 1 : 0), y1 + 1 + i], 1);
drawLine([x1 + 5 - i, y2 - 2 - i], [x1 + 5 + i + (use_fast_draw ? 1 : 0), y2 - 2 - i], 1);
}
}
}
drawTextLabels(horizontal, horizontal ? width : height, x1, y1);
}
function drawTextLabels(horizontal, size, x, y) {
// =======================================================
// Draw Text
// =======================================================
var textLayerRef = layerSetRef.artLayers.add();
textLayerRef.kind = LayerKind.TEXT;
var textItemRef = textLayerRef.textItem;
if (rectangleList.length == 1) {
textItemRef.contents = size + "px";
layerSetRef.name = textItemRef.contents;
}
if (horizontal) {
if (size < 45 || !make_centered_labels) {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.justification = Justification.CENTER;
textItemRef.position = Array(Math.floor(x + (size / 2)), y + 20);
textItemRef.contents = size + "px";
} else {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.justification = Justification.CENTER;
textItemRef.position = Array(Math.floor(x + (size / 2)), y + 8);
textItemRef.contents = size + "px";
loadTransparency();
app.activeDocument.selection.expand(4);
selectLayerBelow();
app.activeDocument.selection.cut();
}
} else {
if (size < 30 || !make_centered_labels) {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.position = Array(x + 12, Math.floor(y + 4 + (size / 2)));
textItemRef.contents = size + "px";
} else {
textItemRef.color = app.foregroundColor; {
if (make_bold_labels) {
textItemRef.font = "Arial-BoldMT";
} else {
textItemRef.font = "ArialMT";
}
}
textItemRef.size = font_size;
textItemRef.antiAliasMethod = AntiAlias.SHARP;
textItemRef.autoKerning = AutoKernType.OPTICAL;
textItemRef.justification = Justification.CENTER;
textItemRef.position = Array(x + 5, Math.floor(y + 4 + (size / 2)));
textItemRef.contents = size + "px";
loadTransparency();
app.activeDocument.selection.expand(4);
selectLayerBelow();
app.activeDocument.selection.cut();
}
}
}
function makeWorkPath(tolerance) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putClass(charIDToTypeID('Path'));
desc.putReference(charIDToTypeID('null'), ref);
var ref2 = new ActionReference();
ref2.putProperty(charIDToTypeID('csel'), charIDToTypeID('fsel'));
desc.putReference(charIDToTypeID('From'), ref2);
desc.putUnitDouble(charIDToTypeID('Tlrn'), charIDToTypeID('#Pxl'), tolerance);
executeAction(charIDToTypeID('Mk '), desc, DialogModes.NO);
}
function makeSelectionF() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty(charIDToTypeID('Chnl'), charIDToTypeID('fsel'));
desc.putReference(charIDToTypeID('null'), ref);
var ref = new ActionReference();
ref.putProperty(charIDToTypeID('Path'), charIDToTypeID('WrPt'));
desc.putReference(charIDToTypeID('T '), ref);
desc.putInteger(charIDToTypeID('Vrsn'), 1);
desc.putBoolean(stringIDToTypeID('vectorMaskParams'), true);
executeAction(charIDToTypeID('setd'), desc, DialogModes.NO);
};
function drawLine_slower(x1, y1, x2, y2) {
var pointArray = new Array();
var pointA = new PathPointInfo();
pointA.kind = PointKind.CORNERPOINT;
pointA.anchor = Array(x1, y1);
pointA.leftDirection = pointA.anchor;
pointA.rightDirection = pointA.anchor;
pointArray.push(pointA);
var pointB = new PathPointInfo();
pointB.kind = PointKind.CORNERPOINT;
pointB.anchor = Array(x2, y2);
pointB.leftDirection = pointB.anchor;
pointB.rightDirection = pointB.anchor;
pointArray.push(pointB);
var line = new SubPathInfo();
line.operation = ShapeOperation.SHAPEXOR;
line.closed = false;
line.entireSubPath = pointArray;
var lineSubPathArray = new Array();
lineSubPathArray.push(line);
var linePath = app.activeDocument.pathItems.add("TempPath", lineSubPathArray);
linePath.strokePath(ToolType.PENCIL, false);
app.activeDocument.pathItems.removeAll();
};
function drawLine(startXY, endXY, width) {
if (!use_fast_draw) return drawLine_slower(startXY[0], startXY[1], endXY[0], endXY[1]);
var desc = new ActionDescriptor();
var lineDesc = new ActionDescriptor();
var startDesc = new ActionDescriptor();
startDesc.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), startXY[0]);
startDesc.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), startXY[1]);
lineDesc.putObject(charIDToTypeID('Strt'), charIDToTypeID('Pnt '), startDesc);
var endDesc = new ActionDescriptor();
endDesc.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), endXY[0]);
endDesc.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), endXY[1]);
lineDesc.putObject(charIDToTypeID('End '), charIDToTypeID('Pnt '), endDesc);
lineDesc.putUnitDouble(charIDToTypeID('Wdth'), charIDToTypeID('#Pxl'), width);
desc.putObject(charIDToTypeID('Shp '), charIDToTypeID('Ln '), lineDesc);
desc.putBoolean(charIDToTypeID('AntA'), false);
executeAction(charIDToTypeID('Draw'), desc, DialogModes.NO);
};
function hasSelection(doc) {
var res = false;
var as = doc.activeHistoryState;
doc.selection.deselect();
if (as != doc.activeHistoryState) {
res = true;
doc.activeHistoryState = as;
}
return res;
}
function selectLayerBelow() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Bckw"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putBoolean(charIDToTypeID("MkVs"), false);
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};
function selectLayerAbove() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Frwr"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putBoolean(charIDToTypeID("MkVs"), false);
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};
function loadTransparency(Invert) {
if (Invert == undefined) Invert = false;
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Chnl"), charIDToTypeID("fsel"));
desc.putReference(charIDToTypeID("null"), ref);
var ref1 = new ActionReference();
ref1.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Trsp"));
desc.putReference(charIDToTypeID("T "), ref1);
desc.putBoolean(charIDToTypeID('Invr'), Invert);
executeAction(charIDToTypeID("setd"), desc, DialogModes.NO);
};
function selectLayerByIndex(index, add) {
add = (add == undefined) ? add = false : add;
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
};
function getActiveLayerIndex() {
var ref = new ActionReference();
ref.putProperty(1349677170, 1232366921);
ref.putEnumerated(1283027488, 1332896878, 1416783732);
try {
activeDocument.backgroundLayer;
var res = executeActionGet(ref)
.getInteger(1232366921) - 1;
} catch (e) {
var res = executeActionGet(ref)
.getInteger(1232366921);
}
return res;
};
function linkSelectedLayers() {
var desc221 = new ActionDescriptor();
var ref142 = new ActionReference();
ref142.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc221.putReference(charIDToTypeID('null'), ref142);
executeAction(stringIDToTypeID('linkSelectedLayers'), desc221, DialogModes.NO);
};
function loadVectorMask() {
// =======================================================
var idsetd = charIDToTypeID("setd");
var desc14 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref9 = new ActionReference();
var idChnl = charIDToTypeID("Chnl");
var idfsel = charIDToTypeID("fsel");
ref9.putProperty(idChnl, idfsel);
desc14.putReference(idnull, ref9);
var idT = charIDToTypeID("T ");
var ref10 = new ActionReference();
var idPath = charIDToTypeID("Path");
var idPath = charIDToTypeID("Path");
var idvectorMask = stringIDToTypeID("vectorMask");
ref10.putEnumerated(idPath, idPath, idvectorMask);
var idLyr = charIDToTypeID("Lyr ");
var idOrdn = charIDToTypeID("Ordn");
var idTrgt = charIDToTypeID("Trgt");
ref10.putEnumerated(idLyr, idOrdn, idTrgt);
desc14.putReference(idT, ref10);
var idVrsn = charIDToTypeID("Vrsn");
desc14.putInteger(idVrsn, 1);
var idvectorMaskParams = stringIDToTypeID("vectorMaskParams");
desc14.putBoolean(idvectorMaskParams, true);
executeAction(idsetd, desc14, DialogModes.NO);
};
function loadLayerMask() {
// =======================================================
var idsetd = charIDToTypeID("setd");
var desc21 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref14 = new ActionReference();
var idChnl = charIDToTypeID("Chnl");
var idfsel = charIDToTypeID("fsel");
ref14.putProperty(idChnl, idfsel);
desc21.putReference(idnull, ref14);
var idT = charIDToTypeID("T ");
var ref15 = new ActionReference();
var idChnl = charIDToTypeID("Chnl");
var idChnl = charIDToTypeID("Chnl");
var idMsk = charIDToTypeID("Msk ");
ref15.putEnumerated(idChnl, idChnl, idMsk);
desc21.putReference(idT, ref15);
executeAction(idsetd, desc21, DialogModes.NO);
};
///////////////////////////////////////////////////////////////////////////////
// Function: hasVectorMask
// Usage: see if there is a vector layer mask
// Input: <none> Must have an open document
// Return: true if there is a vector mask
///////////////////////////////////////////////////////////////////////////////
function hasVectorMask() {
var hasVectorMask = false;
try {
var ref = new ActionReference();
var keyVectorMaskEnabled = app.stringIDToTypeID('vectorMask');
var keyKind = app.charIDToTypeID('Knd ');
ref.putEnumerated(app.charIDToTypeID('Path'), app.charIDToTypeID('Ordn'), keyVectorMaskEnabled);
var desc = executeActionGet(ref);
if (desc.hasKey(keyKind)) {
var kindValue = desc.getEnumerationValue(keyKind);
if (kindValue == keyVectorMaskEnabled) {
hasVectorMask = true;
}
}
} catch (e) {
hasVectorMask = false;
}
return hasVectorMask;
};
function multiselectfontreader() {
// by paul riggott; MULTI-SELECT Function
app.bringToFront();
main();
function main() {
if (!documents.length) return;
var selLayers = [];
selLayers = getSelectedLayersIdx();
for (var a in selLayers) {
makeActiveByIndex(selLayers[a], false);
//amend to suit.
readTextLayer()
}
}
function getSelectedLayersIdx() {
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID('targetLayers'))) {
desc = desc.getList(stringIDToTypeID('targetLayers'));
var c = desc.count
var selectedLayers = new Array();
for (var i = 0; i < c; i++) {
try {
activeDocument.backgroundLayer;
selectedLayers.push(desc.getReference(i)
.getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i)
.getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Prpr"), charIDToTypeID("ItmI"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
try {
activeDocument.backgroundLayer;
selectedLayers.push(executeActionGet(ref)
.getInteger(charIDToTypeID("ItmI")) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref)
.getInteger(charIDToTypeID("ItmI")));
}
}
return selectedLayers;
};
function makeActiveByIndex(idx, visible) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), idx)
desc.putReference(charIDToTypeID("null"), ref);
desc.putBoolean(charIDToTypeID("MkVs"), visible);
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};
};
// Read one or more selected fonts
function readTextLayer() {
if (app.documents.length > 0) {
var myDoc = app.activeDocument;
var myLayer = myDoc.activeLayer;
if (myLayer.kind == LayerKind.TEXT) {
var thisText = myLayer.textItem;
// Renaming the Justifcation info from Justification.CENTER - > Center;
try {
var theJustification = String(thisText.justification)
.replace("Justification.", "")
} catch (e) {
var theJustification = "LEFT"
};
theJustification = theJustification[0] + theJustification.slice(1, theJustification.length)
.toLowerCase();
var fonts = getFonts(app.activeDocument.activeLayer);
for (var i = 0; i < fonts.length; i++) {
addTextLayer(
((fonts.length > 1) ? fonts[i].text + ((fonts[i].text.length) ? "\r" : '') : '') + "Font: " + fonts[i].font + "\r" + "Size: " + fonts[i].size + "\r" + "Color: #" + fonts[i].color.rgb.hexValue + "\r" + ((i === 0 && fonts[i].leading !== '' && TextLeading == true) ? "Leading: " + fonts[i].leading + "\r" : '') + ((i === 0 && TextJustification == true) ? "Justify: " + theJustification + "\r" : ''),
"Font Info #" + (i + 1),
[myLayer.bounds[0] + i * 150, myLayer.bounds[3] + 15]
//Code for dynamically figuring out width hieght canvas size and placing the text objects accordingly//
/*
(myDoc.width > myDoc.height?[myLayer.bounds[0] + i * 150, myLayer.bounds[3] + 15]:[myLayer.bounds[0], myLayer.bounds[3] + i * 100])
*/
);
}
}
}
};
// Add's a text layer which contains the content of the read string above
function addTextLayer(theText, theName, thePosition) {
var aTextLayer = app.activeDocument.artLayers.add();
aTextLayer.kind = LayerKind.TEXT;
aTextLayer.name = theName;
var aTextLayerRef = aTextLayer.textItem;
aTextLayerRef.kind = TextType.POINTTEXT;
aTextLayerRef.size = 10;
aTextLayerRef.font = "Arial-BoldMT";
aTextLayerRef.color = app.foregroundColor;
aTextLayerRef.justification = Justification.LEFT;
aTextLayerRef.position = thePosition;
aTextLayer.blendMode = BlendMode.NORMAL;
aTextLayer.opacity = 100;
aTextLayer.fillOpacity = 100;
aTextLayerRef.useAutoLeading = true;
aTextLayerRef.leading = 0;
aTextLayerRef.horizontalScale = 100;
aTextLayerRef.verticalScale = 100;
aTextLayerRef.contents = theText;
aTextLayerRef.antiAliasMethod = AntiAlias.SHARP;
//Move the newly created font layers into the existing "Pixel Spec" folder
var doc = app.activeDocument;
var srcLayer = doc.activeLayer;
try {
moveLayerToSet(doc, srcLayer, 'Pixel Specs');
} catch (error) {
false;
}
function moveLayerToSet(doc, srcLayer, toLayerName) {
var destLayer = doc.layers[toLayerName];
if (destLayer.layers) destLayer = destLayer.layers[0];
srcLayer.move(destLayer, ElementPlacement.PLACEBEFORE);
}
};
function getColorFromDescriptor(colorDesc, keyClass) {
var colorObject = new SolidColor();
switch (keyClass) {
case "Grsc":
colorObject.grey.grey = color.getDouble(charIDToTypeID('Gry '));
break;
case "RGBC":
colorObject.rgb.red = colorDesc.getDouble(charIDToTypeID('Rd '));
colorObject.rgb.green = colorDesc.getDouble(charIDToTypeID('Grn '));
colorObject.rgb.blue = colorDesc.getDouble(charIDToTypeID('Bl '));
break;
case "CMYC":
colorObject.cmyk.cyan = colorDesc.getDouble(charIDToTypeID('Cyn '));
colorObject.cmyk.magenta = colorDesc.getDouble(charIDToTypeID('Mgnt'));
colorObject.cmyk.yellow = colorDesc.getDouble(charIDToTypeID('Ylw '));
colorObject.cmyk.black = colorDesc.getDouble(charIDToTypeID('Blck'));
break;
case "LbCl":
colorObject.lab.l = colorDesc.getDouble(charIDToTypeID('Lmnc'));
colorObject.lab.a = colorDesc.getDouble(charIDToTypeID('A '));
colorObject.lab.b = colorDesc.getDouble(charIDToTypeID('B '));
break;
default:
return null;
}
return colorObject;
};
// get fonts and other parameters used in type layer
function getFonts(textLayer) {
function markReturnedContentText(text) {
if (font_content_detection) {
return font_content_detection_symbols[0] + text + font_content_detection_symbols[1] + "\r";
} else {
return '';
}
}
if (textLayer.kind == LayerKind.TEXT) {
app.activeDocument.activeLayer = textLayer;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDesc = executeActionGet(ref);
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var rangeList = textDesc.getList(stringIDToTypeID('textStyleRange'));
var fonts = [];
for (var m = 0; m < rangeList.count; m++) {
var styleDesc = rangeList.getObjectValue(m)
.getObjectValue(stringIDToTypeID('textStyle'));
var aFrom = rangeList.getObjectValue(m)
.getInteger(stringIDToTypeID('from'));
var aTo = rangeList.getObjectValue(m)
.getInteger(stringIDToTypeID('to'));
if (m > 0) {
if (rangeList.getObjectValue(m - 1)
.getInteger(stringIDToTypeID('from')) == aFrom && rangeList.getObjectValue(m - 1)
.getInteger(stringIDToTypeID('to')) == aTo) continue;
}
var theLetters = app.activeDocument.activeLayer.textItem.contents.substring(aFrom, aTo);
var aFont = styleDesc.getString(stringIDToTypeID('fontPostScriptName'));
//var aSize = styleDesc.getUnitDoubleValue(stringIDToTypeID('size')) + " " + typeIDToCharID(styleDesc.getUnitDoubleType(stringIDToTypeID('size')));
var aSize = new UnitValue(styleDesc.getUnitDoubleValue(stringIDToTypeID('size')), "px");
//Check if font has been transformed
if (textDesc.hasKey(stringIDToTypeID('transform'))) {
var mFactor = textDesc.getObjectValue(stringIDToTypeID('transform')).getUnitDoubleValue (stringIDToTypeID("yy") );
aSize = Math.round(aSize * mFactor);
}
var aColor = getColorFromDescriptor(styleDesc.getObjectValue(charIDToTypeID("Clr ")), typeIDToCharID(styleDesc.getClass(charIDToTypeID("Clr "))));
if (styleDesc.hasKey(stringIDToTypeID('leading'))) {
var aLeading = new UnitValue(styleDesc.getUnitDoubleValue(stringIDToTypeID('leading')), "px");
} else {
var aLeading = "";
}
var txt = theLetters.replace(/^\s+/, '').replace(/\s+$/, '');
var merged = false;
if (txt.length > 0) {
for (var x = 0; x < m; x++) {
try {
if (fonts[x].font === aFont && fonts[x].size === aSize && fonts[x].color.rgb.hexValue === aColor.rgb.hexValue && fonts[x].leading === aLeading) {
// It's a hack!!!
if (fonts[x].text !== txt) {
fonts[x].text += markReturnedContentText(txt);
}
merged = true;
}
} catch (e) {}
}
if (!merged) {
fonts.push({
text: markReturnedContentText(txt),
font: aFont,
size: aSize,
color: aColor,
leading: aLeading
});
}
}
};
return fonts;
}
};
-
david
Script for Splitting Layers
I wrote a script for splitting a layer. I refined it a bit when I saw the version here.
This one will work with with objects separated by any distance. (I scale the thresholded channel to 200% using nearest neighbor then use "selection.makeWorkPath(0.5)" to make a path that perfectly follows the bitmap)
It can also handle objects with holes and nested objects.
I still need to clean up the code a bit and add some error handling.
Code: Select all#target photoshop
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
//main() //uncomment this line and comment the next to see history states.
activeDocument.suspendHistory("Separate","main()");
app.preferences.rulerUnits = originalRulerUnits;
function main(){
var idsetd = charIDToTypeID( "setd" );
var desc922 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref529 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref529.putProperty( idChnl, idfsel );
desc922.putReference( idnull, ref529 );
var idT = charIDToTypeID( "T " );
var ref530 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idTrsp = charIDToTypeID( "Trsp" );
ref530.putEnumerated( idChnl, idChnl, idTrsp );
desc922.putReference( idT, ref530 );
executeAction( idsetd, desc922, DialogModes.NO );
activeDocument.quickMaskMode=true;
activeDocument.activeLayer.threshold (1);
var idMk = charIDToTypeID( "Mk " );
var desc642 = new ActionDescriptor();
var idNw = charIDToTypeID( "Nw " );
var idDcmn = charIDToTypeID( "Dcmn" );
desc642.putClass( idNw, idDcmn );
var idUsng = charIDToTypeID( "Usng" );
var ref535 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref535.putEnumerated( idChnl, idOrdn, idTrgt );
desc642.putReference( idUsng, ref535 );
executeAction( idMk, desc642, DialogModes.NO );
// =======================================================
activeDocument.resizeImage("200%", "200%", undefined, ResampleMethod.NEARESTNEIGHBOR)
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc934 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref535 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref535.putProperty( idChnl, idfsel );
desc934.putReference( idnull, ref535 );
var idT = charIDToTypeID( "T " );
var ref536 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref536.putEnumerated( idChnl, idOrdn, idTrgt );
desc934.putReference( idT, ref536 );
executeAction( idsetd, desc934, DialogModes.NO );
activeDocument.selection.makeWorkPath(0.5);
// =======================================================
activeDocument.resizeImage("50%", "50%", undefined, ResampleMethod.NEARESTNEIGHBOR)
var pathInfo=collectPathInfoFromDesc (activeDocument, activeDocument.pathItems[activeDocument.pathItems.length-1])
var subPathsLength= activeDocument.pathItems[0].subPathItems.length
// =======================================================
var idCls = charIDToTypeID( "Cls " );
var desc974 = new ActionDescriptor();
var idSvng = charIDToTypeID( "Svng" );
var idYsN = charIDToTypeID( "YsN " );
var idN = charIDToTypeID( "N " );
desc974.putEnumerated( idSvng, idYsN, idN );
executeAction( idCls, desc974, DialogModes.NO );
// =======================================================
activeDocument.quickMaskMode=false
// =======================================================
//make channel
// =======================================================
var idMk = charIDToTypeID( "Mk " );
var desc6 = new ActionDescriptor();
var idNw = charIDToTypeID( "Nw " );
var desc7 = new ActionDescriptor();
var idNm = charIDToTypeID( "Nm " );
desc7.putString( idNm, "ContiguityMask" );
var idClrI = charIDToTypeID( "ClrI" );
var idMskI = charIDToTypeID( "MskI" );
var idMskA = charIDToTypeID( "MskA" );
desc7.putEnumerated( idClrI, idMskI, idMskA );
var idClr = charIDToTypeID( "Clr " );
var desc8 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc8.putDouble( idRd, 255.000000 );
var idGrn = charIDToTypeID( "Grn " );
desc8.putDouble( idGrn, 0.000000 );
var idBl = charIDToTypeID( "Bl " );
desc8.putDouble( idBl, 0.000000 );
var idRGBC = charIDToTypeID( "RGBC" );
desc7.putObject( idClr, idRGBC, desc8 );
var idOpct = charIDToTypeID( "Opct" );
desc7.putInteger( idOpct, 50 );
var idChnl = charIDToTypeID( "Chnl" );
desc6.putObject( idNw, idChnl, desc7 );
var idUsng = charIDToTypeID( "Usng" );
var ref5 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref5.putProperty( idChnl, idfsel );
desc6.putReference( idUsng, ref5 );
executeAction( idMk, desc6, DialogModes.NO );
for(i=0;i<subPathsLength;i++){
//deselect
var idsetd = charIDToTypeID( "setd" );
var desc279 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref137 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref137.putProperty( idChnl, idfsel );
desc279.putReference( idnull, ref137 );
var idT = charIDToTypeID( "T " );
var idOrdn = charIDToTypeID( "Ordn" );
var idNone = charIDToTypeID( "None" );
desc279.putEnumerated( idT, idOrdn, idNone );
executeAction( idsetd, desc279, DialogModes.NO );
///select alpha channel
var idslct = charIDToTypeID( "slct" );
var desc315 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref175 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
ref175.putName( idChnl, "ContiguityMask" );
desc315.putReference( idnull, ref175 );
executeAction( idslct, desc315, DialogModes.NO );
//use magic wand
var idsetd = charIDToTypeID( "setd" );
var desc263 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref123 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref123.putProperty( idChnl, idfsel );
desc263.putReference( idnull, ref123 );
var idT = charIDToTypeID( "T " );
var desc264 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idRlt = charIDToTypeID( "#Rlt" );
desc264.putUnitDouble( idHrzn, idRlt, pathInfo[0][0]);
var idVrtc = charIDToTypeID( "Vrtc" );
var idRlt = charIDToTypeID( "#Rlt" );
desc264.putUnitDouble( idVrtc, idRlt, pathInfo[0][1]);
var idPnt = charIDToTypeID( "Pnt " );
desc263.putObject( idT, idPnt, desc264 );
var idTlrn = charIDToTypeID( "Tlrn" );
desc263.putInteger( idTlrn, 1 );
executeAction( idsetd, desc263, DialogModes.NO );
var idslct = charIDToTypeID( "slct" );
var desc346 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref205 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idRGB = charIDToTypeID( "RGB " );
ref205.putEnumerated( idChnl, idChnl, idRGB );
desc346.putReference( idnull, ref205 );
var idMkVs = charIDToTypeID( "MkVs" );
desc346.putBoolean( idMkVs, false );
executeAction( idslct, desc346, DialogModes.NO );
try{
// =======================================================
var idCpTL = charIDToTypeID( "CpTL" );
executeAction( idCpTL, undefined, DialogModes.NO );
var idslct = charIDToTypeID( "slct" );
var desc348 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref206 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idBckw = charIDToTypeID( "Bckw" );
ref206.putEnumerated( idLyr, idOrdn, idBckw );
desc348.putReference( idnull, ref206 );
var idMkVs = charIDToTypeID( "MkVs" );
desc348.putBoolean( idMkVs, false );
executeAction( idslct, desc348, DialogModes.NO );
}catch(e){}
}
var idsetd = charIDToTypeID( "setd" );
var desc1045 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref578 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref578.putProperty( idChnl, idfsel );
desc1045.putReference( idnull, ref578 );
var idT = charIDToTypeID( "T " );
var idOrdn = charIDToTypeID( "Ordn" );
var idNone = charIDToTypeID( "None" );
desc1045.putEnumerated( idT, idOrdn, idNone );
executeAction( idsetd, desc1045, DialogModes.NO );
// =======================================================
var idDlt = charIDToTypeID( "Dlt " );
var desc694 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref323 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
ref323.putName( idChnl, "ContiguityMask" );
desc694.putReference( idnull, ref323 );
executeAction( idDlt, desc694, DialogModes.NO );
var idHd = charIDToTypeID( "Hd " );
var desc736 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list22 = new ActionList();
var ref541 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref541.putEnumerated( idLyr, idOrdn, idTrgt );
list22.putReference( ref541 );
desc736.putList( idnull, list22 );
executeAction( idHd, desc736, DialogModes.NO );
}
function collectPathInfoFromDesc (myDocument, thePath) {
var myDocument = app.activeDocument;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
for (var l = 0; l < myDocument.pathItems.length; l++) {
var thisPath = myDocument.pathItems[l];
if (thisPath == thePath && thisPath.name == "Work Path") {
ref.putProperty(cTID("Path"), cTID("WrPt"));
};
if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {
ref.putIndex(cTID("Path"), l + 1);
};
if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {
var idPath = charIDToTypeID( "Path" );
var idPath = charIDToTypeID( "Path" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
ref.putEnumerated( idPath, idPath, idvectorMask );
};
};
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
// for subpathitem’s count;
for (var n = 0; n < listKey.count; n++) {
var points = listKey.getObjectValue(n).getList(sTID('points'));
// get first point;
var anchorObj = points.getObjectValue(0).getObjectValue(sTID("anchor"));
var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
var thisPoint = [anchor];
theArray.push(thisPoint);
};
};
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
return theArray;
};
edit: I suppose you may still want an expansion setting, but I would do it with the initial selection, instead of with every sub-path.
This one will work with with objects separated by any distance. (I scale the thresholded channel to 200% using nearest neighbor then use "selection.makeWorkPath(0.5)" to make a path that perfectly follows the bitmap)
It can also handle objects with holes and nested objects.
I still need to clean up the code a bit and add some error handling.
Code: Select all#target photoshop
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
//main() //uncomment this line and comment the next to see history states.
activeDocument.suspendHistory("Separate","main()");
app.preferences.rulerUnits = originalRulerUnits;
function main(){
var idsetd = charIDToTypeID( "setd" );
var desc922 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref529 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref529.putProperty( idChnl, idfsel );
desc922.putReference( idnull, ref529 );
var idT = charIDToTypeID( "T " );
var ref530 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idTrsp = charIDToTypeID( "Trsp" );
ref530.putEnumerated( idChnl, idChnl, idTrsp );
desc922.putReference( idT, ref530 );
executeAction( idsetd, desc922, DialogModes.NO );
activeDocument.quickMaskMode=true;
activeDocument.activeLayer.threshold (1);
var idMk = charIDToTypeID( "Mk " );
var desc642 = new ActionDescriptor();
var idNw = charIDToTypeID( "Nw " );
var idDcmn = charIDToTypeID( "Dcmn" );
desc642.putClass( idNw, idDcmn );
var idUsng = charIDToTypeID( "Usng" );
var ref535 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref535.putEnumerated( idChnl, idOrdn, idTrgt );
desc642.putReference( idUsng, ref535 );
executeAction( idMk, desc642, DialogModes.NO );
// =======================================================
activeDocument.resizeImage("200%", "200%", undefined, ResampleMethod.NEARESTNEIGHBOR)
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc934 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref535 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref535.putProperty( idChnl, idfsel );
desc934.putReference( idnull, ref535 );
var idT = charIDToTypeID( "T " );
var ref536 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref536.putEnumerated( idChnl, idOrdn, idTrgt );
desc934.putReference( idT, ref536 );
executeAction( idsetd, desc934, DialogModes.NO );
activeDocument.selection.makeWorkPath(0.5);
// =======================================================
activeDocument.resizeImage("50%", "50%", undefined, ResampleMethod.NEARESTNEIGHBOR)
var pathInfo=collectPathInfoFromDesc (activeDocument, activeDocument.pathItems[activeDocument.pathItems.length-1])
var subPathsLength= activeDocument.pathItems[0].subPathItems.length
// =======================================================
var idCls = charIDToTypeID( "Cls " );
var desc974 = new ActionDescriptor();
var idSvng = charIDToTypeID( "Svng" );
var idYsN = charIDToTypeID( "YsN " );
var idN = charIDToTypeID( "N " );
desc974.putEnumerated( idSvng, idYsN, idN );
executeAction( idCls, desc974, DialogModes.NO );
// =======================================================
activeDocument.quickMaskMode=false
// =======================================================
//make channel
// =======================================================
var idMk = charIDToTypeID( "Mk " );
var desc6 = new ActionDescriptor();
var idNw = charIDToTypeID( "Nw " );
var desc7 = new ActionDescriptor();
var idNm = charIDToTypeID( "Nm " );
desc7.putString( idNm, "ContiguityMask" );
var idClrI = charIDToTypeID( "ClrI" );
var idMskI = charIDToTypeID( "MskI" );
var idMskA = charIDToTypeID( "MskA" );
desc7.putEnumerated( idClrI, idMskI, idMskA );
var idClr = charIDToTypeID( "Clr " );
var desc8 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc8.putDouble( idRd, 255.000000 );
var idGrn = charIDToTypeID( "Grn " );
desc8.putDouble( idGrn, 0.000000 );
var idBl = charIDToTypeID( "Bl " );
desc8.putDouble( idBl, 0.000000 );
var idRGBC = charIDToTypeID( "RGBC" );
desc7.putObject( idClr, idRGBC, desc8 );
var idOpct = charIDToTypeID( "Opct" );
desc7.putInteger( idOpct, 50 );
var idChnl = charIDToTypeID( "Chnl" );
desc6.putObject( idNw, idChnl, desc7 );
var idUsng = charIDToTypeID( "Usng" );
var ref5 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref5.putProperty( idChnl, idfsel );
desc6.putReference( idUsng, ref5 );
executeAction( idMk, desc6, DialogModes.NO );
for(i=0;i<subPathsLength;i++){
//deselect
var idsetd = charIDToTypeID( "setd" );
var desc279 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref137 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref137.putProperty( idChnl, idfsel );
desc279.putReference( idnull, ref137 );
var idT = charIDToTypeID( "T " );
var idOrdn = charIDToTypeID( "Ordn" );
var idNone = charIDToTypeID( "None" );
desc279.putEnumerated( idT, idOrdn, idNone );
executeAction( idsetd, desc279, DialogModes.NO );
///select alpha channel
var idslct = charIDToTypeID( "slct" );
var desc315 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref175 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
ref175.putName( idChnl, "ContiguityMask" );
desc315.putReference( idnull, ref175 );
executeAction( idslct, desc315, DialogModes.NO );
//use magic wand
var idsetd = charIDToTypeID( "setd" );
var desc263 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref123 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref123.putProperty( idChnl, idfsel );
desc263.putReference( idnull, ref123 );
var idT = charIDToTypeID( "T " );
var desc264 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idRlt = charIDToTypeID( "#Rlt" );
desc264.putUnitDouble( idHrzn, idRlt, pathInfo[0][0]);
var idVrtc = charIDToTypeID( "Vrtc" );
var idRlt = charIDToTypeID( "#Rlt" );
desc264.putUnitDouble( idVrtc, idRlt, pathInfo[0][1]);
var idPnt = charIDToTypeID( "Pnt " );
desc263.putObject( idT, idPnt, desc264 );
var idTlrn = charIDToTypeID( "Tlrn" );
desc263.putInteger( idTlrn, 1 );
executeAction( idsetd, desc263, DialogModes.NO );
var idslct = charIDToTypeID( "slct" );
var desc346 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref205 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idRGB = charIDToTypeID( "RGB " );
ref205.putEnumerated( idChnl, idChnl, idRGB );
desc346.putReference( idnull, ref205 );
var idMkVs = charIDToTypeID( "MkVs" );
desc346.putBoolean( idMkVs, false );
executeAction( idslct, desc346, DialogModes.NO );
try{
// =======================================================
var idCpTL = charIDToTypeID( "CpTL" );
executeAction( idCpTL, undefined, DialogModes.NO );
var idslct = charIDToTypeID( "slct" );
var desc348 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref206 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idBckw = charIDToTypeID( "Bckw" );
ref206.putEnumerated( idLyr, idOrdn, idBckw );
desc348.putReference( idnull, ref206 );
var idMkVs = charIDToTypeID( "MkVs" );
desc348.putBoolean( idMkVs, false );
executeAction( idslct, desc348, DialogModes.NO );
}catch(e){}
}
var idsetd = charIDToTypeID( "setd" );
var desc1045 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref578 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref578.putProperty( idChnl, idfsel );
desc1045.putReference( idnull, ref578 );
var idT = charIDToTypeID( "T " );
var idOrdn = charIDToTypeID( "Ordn" );
var idNone = charIDToTypeID( "None" );
desc1045.putEnumerated( idT, idOrdn, idNone );
executeAction( idsetd, desc1045, DialogModes.NO );
// =======================================================
var idDlt = charIDToTypeID( "Dlt " );
var desc694 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref323 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
ref323.putName( idChnl, "ContiguityMask" );
desc694.putReference( idnull, ref323 );
executeAction( idDlt, desc694, DialogModes.NO );
var idHd = charIDToTypeID( "Hd " );
var desc736 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list22 = new ActionList();
var ref541 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref541.putEnumerated( idLyr, idOrdn, idTrgt );
list22.putReference( ref541 );
desc736.putList( idnull, list22 );
executeAction( idHd, desc736, DialogModes.NO );
}
function collectPathInfoFromDesc (myDocument, thePath) {
var myDocument = app.activeDocument;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
for (var l = 0; l < myDocument.pathItems.length; l++) {
var thisPath = myDocument.pathItems[l];
if (thisPath == thePath && thisPath.name == "Work Path") {
ref.putProperty(cTID("Path"), cTID("WrPt"));
};
if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {
ref.putIndex(cTID("Path"), l + 1);
};
if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {
var idPath = charIDToTypeID( "Path" );
var idPath = charIDToTypeID( "Path" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
ref.putEnumerated( idPath, idPath, idvectorMask );
};
};
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
// for subpathitem’s count;
for (var n = 0; n < listKey.count; n++) {
var points = listKey.getObjectValue(n).getList(sTID('points'));
// get first point;
var anchorObj = points.getObjectValue(0).getObjectValue(sTID("anchor"));
var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
var thisPoint = [anchor];
theArray.push(thisPoint);
};
};
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
return theArray;
};
edit: I suppose you may still want an expansion setting, but I would do it with the initial selection, instead of with every sub-path.
-
pfaffenbichler
Script for Splitting Layers
On a slightly different but similar topic, remember the text splitter script I posted earlier regarding having the ability to combine....The amount of possible settings to first check for and then implement in the creation of a new text layer makes the task seem just to tedious for my tastes.
-
mycort
Script for Splitting Layers
no problem and thanks alot for all your work already, your time and effort is appreciated greatly.