Input image is difficult to work with because there're...
- strokes that should be ignored but it may be difficult to set specific conditions for that
- spots with different transparency
- spots almost fused with strokes (between slices 9 and 12 in your example)
here's how I'd approach this. Let's say those are my spots image. Arrows indicate problematic sections.
Then I'd create a helper-layer: a copy of this layer, where I'd manually remove the parts I don't need and make half-transparent spots more obvious. It doesn't need to be perfect, just a quick strong indication to help the script recognize the regions:
Then the script would do the following:
- use Magic Wand in the top-left corner with
Contiguous
option turned on and Tolerance
set to 0 and invert selection, like this I'll get selections of all the regions I need:
- I'll
Expand
selection a bit (2px for instance) and since Selection
object in Photoshop doesn't have separate coordinates for each selection island, I'll convert selection to paths first
- Now I can loop through separate paths, recreate them and load each one as a selection, get
selection.bounds
and make a slice based on these bounds. Final result with original layer displayed:
P.S. not sure if you need specifically Slices or it was the first thing came to mind? If you simply need to generate a list of coordinated of bounding boxes, you can write them to a file or clipboard and read in Unity later.
Final code:
function main()
{
var pathPoints = [];
magicWand();
invertSelection();
expandSelection(2);
selectionToPath(.7);
var workPath = activeDocument.pathItems[0];
for (i = 0; i < workPath.subPathItems.length; i++)
{
var tempAr = [];
for (var k = 0; k < workPath.subPathItems[i].pathPoints.length; k++)
{
tempAr.push([
workPath.subPathItems[i].pathPoints[k].anchor,
workPath.subPathItems[i].pathPoints[k].leftDirection,
workPath.subPathItems[i].pathPoints[k].rightDirection
]);
};
pathPoints.push(tempAr);
};
for (var i = 0; i < pathPoints.length; i++)
{
createPath(pathPoints[i]);
loadSelectionFromPath();
var bounds = activeDocument.selection.bounds;
makeSlice(bounds);
deselect();
}
activeDocument.pathItems[0].remove();
/////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
function cTID(s)
{
return app.charIDToTypeID(s);
};
function sTID(s)
{
return app.stringIDToTypeID(s);
};
function makeSlice(data)
{
var desc2 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putClass(sTID('slice'));
desc2.putReference(cTID('null'), ref1);
var desc3 = new ActionDescriptor();
desc3.putEnumerated(cTID('Type'), sTID('sliceType'), sTID('user'));
var desc4 = new ActionDescriptor();
desc4.putUnitDouble(cTID('Top '), cTID('#Pxl'), data[1]);
desc4.putUnitDouble(cTID('Left'), cTID('#Pxl'), data[0]);
desc4.putUnitDouble(cTID('Btom'), cTID('#Pxl'), data[3]);
desc4.putUnitDouble(cTID('Rght'), cTID('#Pxl'), data[2]);
desc3.putObject(cTID('At '), cTID('Rctn'), desc4);
desc2.putObject(cTID('Usng'), sTID('slice'), desc3);
executeAction(cTID('Mk '), desc2, DialogModes.NO);
}; // end of makeSlice()
function createPath(_path)
{
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(charIDToTypeID('Path'), charIDToTypeID('WrPt'));
desc1.putReference(charIDToTypeID('null'), ref1);
var list1 = new ActionList();
var desc20 = new ActionDescriptor();
desc20.putEnumerated(stringIDToTypeID("shapeOperation"), stringIDToTypeID("shapeOperation"), stringIDToTypeID('add'));
var list4 = new ActionList();
var desc21 = new ActionDescriptor();
var list5 = new ActionList();
desc21.putBoolean(charIDToTypeID('Clsp'), true);
for (var p = 0; p < _path.length; p++)
{
var desc22 = new ActionDescriptor();
var desc23 = new ActionDescriptor();
desc23.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), _path[p][0][0]);
desc23.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), _path[p][0][1]);
desc22.putObject(charIDToTypeID('Anch'), charIDToTypeID('Pnt '), desc23);
var desc24 = new ActionDescriptor();
desc24.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), _path[p][1][0]);
desc24.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), _path[p][1][1]);
desc22.putObject(charIDToTypeID('Fwd '), charIDToTypeID('Pnt '), desc24);
var desc25 = new ActionDescriptor();
desc25.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), _path[p][2][0]);
desc25.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), _path[p][2][1]);
desc22.putObject(charIDToTypeID('Bwd '), charIDToTypeID('Pnt '), desc25);
list5.putObject(charIDToTypeID('Pthp'), desc22);
}
desc21.putList(charIDToTypeID('Pts '), list5);
list4.putObject(charIDToTypeID('Sbpl'), desc21);
desc20.putList(charIDToTypeID('SbpL'), list4);
list1.putObject(charIDToTypeID('PaCm'), desc20);
desc1.putList(charIDToTypeID('T '), list1);
executeAction(charIDToTypeID('setd'), desc1, DialogModes.NO);
}; // end of createPath()
function magicWand()
{
var desc3904 = new ActionDescriptor();
var ref621 = new ActionReference();
ref621.putProperty(cTID('Chnl'), cTID('fsel'));
desc3904.putReference(cTID('null'), ref621);
var desc3905 = new ActionDescriptor();
desc3905.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), 0);
desc3905.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), 0);
desc3904.putObject(cTID('T '), cTID('Pnt '), desc3905);
desc3904.putInteger(cTID('Tlrn'), 0);
desc3904.putBoolean(cTID('Mrgd'), false);
desc3904.putBoolean(cTID('AntA'), true);
desc3904.putBoolean(cTID('Cntg'), true);
executeAction(cTID('setd'), desc3904, DialogModes.NO);
}; // end of magicWand()
function invertSelection()
{
executeAction(cTID('Invs'), undefined, DialogModes.NO);
}; // end of invertSelection()
function expandSelection(value)
{
var desc62 = new ActionDescriptor();
desc62.putUnitDouble(cTID('By '), cTID('#Pxl'), value);
desc62.putBoolean(sTID('selectionModifyEffectAtCanvasBounds'), true);
executeAction(cTID('Expn'), desc62, DialogModes.NO);
}; // end of expandSelection()
function selectionToPath(value)
{
var desc12 = new ActionDescriptor();
var ref7 = new ActionReference();
ref7.putClass(cTID('Path'));
desc12.putReference(cTID('null'), ref7);
var ref8 = new ActionReference();
ref8.putProperty(cTID('csel'), cTID('fsel'));
desc12.putReference(cTID('From'), ref8);
desc12.putUnitDouble(cTID('Tlrn'), cTID('#Pxl'), value);
executeAction(cTID('Mk '), desc12, DialogModes.NO);
}; // end of selectionToPath()
function loadSelectionFromPath()
{
var desc92 = new ActionDescriptor();
var ref20 = new ActionReference();
ref20.putProperty(cTID('Chnl'), cTID('fsel'));
desc92.putReference(cTID('null'), ref20);
var ref21 = new ActionReference();
ref21.putProperty(cTID('Path'), cTID('WrPt'));
desc92.putReference(cTID('T '), ref21);
desc92.putInteger(cTID('Vrsn'), 1);
desc92.putBoolean(sTID('vectorMaskParams'), true);
executeAction(cTID('setd'), desc92, DialogModes.NO);
}; // end of loadSelectionFromPath()
function deselect()
{
var desc5 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(cTID('Chnl'), cTID('fsel'));
desc5.putReference(cTID('null'), ref1);
desc5.putEnumerated(cTID('T '), cTID('Ordn'), cTID('None'));
executeAction(cTID('setd'), desc5, DialogModes.NO);
}; // end of deselect()
}
app.activeDocument.suspendHistory("create slices based on transparency", "main()");