Copy link to clipboard
Copied
Hello everyone! I have a picture of different shapes like this, the purpose is to create games for preschool kids.
My goal is for my students to take shapes that bear their name, then cut them out and name the shapes.
However, the process of inserting text also takes quite a bit of time. First, I put the text on the shape, then used the magic wand to select the area of the shape below and used the align tool. I keep repeating that process with each text and shape layer.
The problem is, there are too many students to do this and I can't just paste the name, select the area, and center each one. (I have a bit of OCD so I was assigned this job.)
Does someone have a faster solution? Such as an action or script that automatically selects the area outside the text while also being inside the shape?
Thank you everyone for help!
Copy link to clipboard
Copied
Are each of this shapes a separate layer? If so it should be fairly easy to create a CVS file with the names, then import them into the image and align them with each shape layer.
Copy link to clipboard
Copied
Sorry to say no, I use the provided vector image as png. Actually I need this action/script for other things too, like placing text layers in the center of text boxes in series of illustrated story pages (The boxes are arranged above or below the illustrations, I can't control them all)
Or you can help me create operations for each text layer, just skip the step of selecting the shape area. I can run for each text one by one.
Copy link to clipboard
Copied
There are probably many ways to do this (with scripts for example) but one solution would simply be to use guides and snapping and let the text align by itself while moving it.
Since your shapes seem to be aligned in rows and columns, you could set up guides that cross each shape right at the center, and provided you enable snapping, your text will snap at the intersection of these guides for each shape.
If you know how your shapes are laid-out (eg: how many pixels separate them top bottom and sides) you could even build yor guides using the guide layout menu. This is particularly helpful if you are to use this kind of layout repeatedly.
That's a quick and dirty method which is, of course, not necessarily the most automated one.
But it may help...
see that one:
https://helpx.adobe.com/uk/photoshop/using/grid-guides.html
particularly the bit "work efficiently with smart guides"
and that one:
https://helpx.adobe.com/uk/photoshop/how-to/align-objects-guides.html
You could aslo use actions to place a particular line of text at a particular position. But of course you must record those positions first, so, if you have to do it for one file, it isn't worth the trouble. If you have multiple ones to do with the same absolute position for placing each text then, that's another story.
Copy link to clipboard
Copied
Can you explain your problem further. I would like to understand your problem in the first place. At the moment I can not follow nor understand what is actual problem:
"Such as an action or script that automatically selects the area outside the text while also being inside the shape?"
First of all do you want to select text inverse while staying inside boundries of shape to which text ois aligned?
Copy link to clipboard
Copied
Try this script. You have to do some setup first.
1. Create a folder on your desktop named "Names in Shapes".
2. Create a spreadsheet file with the exact number of names as you have shapes, and put all the names in one column.
3. save the spreadsheet as a csv file to the Names in Shape folder on your desktop.
4. Open your image file and put guides across the shapes (they don't have to be centered, they just have to go over the shapes.
Run the script.
#target photoshop
var nameFile = new File ('~/desktop/Names in Shapes/names.csv')
var doc = activeDocument
var origPrefs = app.preferences.rulerUnits
var tempL
//app.preferences.rulerUnits = Units.POINTS;
var docG = doc.guides
var gH = []
var gV = []
var exitLoop = false;
//read names
var nameList = readFile (nameFile).split('\n');
for (var i=0;i<docG.length;i++){
if(docG[i].direction == 'Direction.HORIZONTAL' && (docG[i].coordinate.value !=0 && docG[i].coordinate.value !=doc.height.value)){
gH.push(docG[i].coordinate.value)
}
else if(docG[i].coordinate !=0 && docG[i].coordinate.value !=doc.width.value){gV.push(docG[i].coordinate.value)}
}
gH.sort (function(a, b){return a - b});
gV.sort (function(a, b){return a - b});
var ptArray =[];
for (var i=0;i<gH.length;i++){
for (var j=0;j<gV.length;j++){
ptArray.push([gV[j],gH[i]]);
}
}
tempLayer ();
tempL = doc.activeLayer;
for(var i=0;i<nameList.length;i++){
try{
$.writeln(nameList[i])
$.writeln(ptArray[i])
mWand (ptArray[i][0], ptArray[i][1]);
var selB = doc.selection.bounds;
xCenter = (selB[0] + selB[2])/2
yCenter = (selB[1] + selB[3])/2
deselectS ();
var artLayerRef = doc.artLayers.add()
artLayerRef.kind = LayerKind.TEXT;
var textItemRef = artLayerRef.textItem;
textItemRef.contents = nameList[i];
var tLayer = doc.activeLayer;
var tBounds = tLayer.bounds;
var tXCenter = (tBounds[0] + tBounds[2])/2;
var tYCenter = (tBounds[1] + tBounds[3])/2;
tLayer.translate (xCenter - tXCenter, yCenter - tYCenter)
doc.activeLayer = tempL;
}
catch(e){}
}
doc.activeLayer = tempL;
tempL.remove()
function tempLayer(){
//dup layer
var idCpTL = charIDToTypeID( "CpTL" );
executeAction( idCpTL, undefined, DialogModes.NO );
mWand (5, 5);
invertSel ();
// fill with black
var idFl = charIDToTypeID( "Fl " );
var desc42 = new ActionDescriptor();
var idUsng = charIDToTypeID( "Usng" );
var idFlCn = charIDToTypeID( "FlCn" );
var idFrgC = charIDToTypeID( "FrgC" );
desc42.putEnumerated( idUsng, idFlCn, idFrgC );
executeAction( idFl, desc42, DialogModes.NO );
invertSel ();
//delete BG
var idDlt = charIDToTypeID( "Dlt " );
executeAction( idDlt, undefined, DialogModes.NO );
deselectS ();
}
function deselectS (){
var idsetd = charIDToTypeID( "setd" );
var desc49 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref4 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref4.putProperty( idChnl, idfsel );
desc49.putReference( idnull, ref4 );
var idT = charIDToTypeID( "T " );
var idOrdn = charIDToTypeID( "Ordn" );
var idNone = charIDToTypeID( "None" );
desc49.putEnumerated( idT, idOrdn, idNone );
executeAction( idsetd, desc49, DialogModes.NO );
}
function invertSel(){
var idInvs = charIDToTypeID( "Invs" );
executeAction( idInvs, undefined, DialogModes.NO );
}
function mWand(x1,y1){
var idsetd = charIDToTypeID( "setd" );
var desc27 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref2 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref2.putProperty( idChnl, idfsel );
desc27.putReference( idnull, ref2 );
var idT = charIDToTypeID( "T " );
var desc28 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc28.putUnitDouble( idHrzn, idPxl, x1 );
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc28.putUnitDouble( idVrtc, idPxl, y1 );
var idPnt = charIDToTypeID( "Pnt " );
desc27.putObject( idT, idPnt, desc28 );
var idTlrn = charIDToTypeID( "Tlrn" );
desc27.putInteger( idTlrn, 15 );
var idAntA = charIDToTypeID( "AntA" );
desc27.putBoolean( idAntA, true );
executeAction( idsetd, desc27, DialogModes.NO );
}
function readFile(file) {
if (!file.exists) {
alert( "Cannot find file: " + deodeURI(file.absoluteURI));
}
else{
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return str;
};
};
Copy link to clipboard
Copied
Thank you very much! This really helped me!
Copy link to clipboard
Copied
Glad it helps you!