Copy link to clipboard
Copied
Hi,
I'm in desperate need of a script to export the coordinates of lines, or paths, it doesn't really matter, into a text document.
I've set my ruler up so the 0,0 is in the center of the image, because I need both 0,0 and -0,-0 to work for what I have in mind, basically using a document as a large Cartesian grid, which you can then extract coordinates of 'edges' or end points of lines from.
A little background on why I need it, for anyone curious. I figured out a way to build new worlds/maps for a game that generates terrain based on 'boundaries', which are drawn on, in a 2d plane, but I need coordinates to map these boundaries correctly. I could do it manually, where I'd hover my mouse over every edge or end of the line point, but this would save a LOT of time.
I'd be insanely grateful if anyone can help me out. I've tried looking for scripts or other software, but haven't been successful at all for what I really need.
The way I have my document setup is, 1 pixel per cm, 16384x16384cm. It's quite large, so most 'graph' software won't work for it. The grid itself works fairly well, I just need a decent way to export the coordinates from it.
Thanks in advance!
Edit:
Here, I made an example of a rectangle to give you guys the idea of which coordinates I'd need:
...var dataFile = new File('~/desktop/exportData.txt');
var doc = app.activeDocument;
var dataStream = "";
// loop the paths in the document
for(var pathIndex =0; pathIndex<doc.pathItems.length;pathIndex++){
var pathItem = doc.pathItems[pathIndex];
// for every path output the name
dataStream = dataStream+pathItem.name+'\t';
for(var subPathIndex = 0;subPathIndex<pathItem.subPathItems.length;subPathIndex++){
for(var pointIndex = 0;pointIndex<pathItem.subPathItems[subPathIndex].pathPoi
Copy link to clipboard
Copied
This is an example of how to export the path points of the shape layer to a tab separated value text file.
var dataFile = new File('~/desktop/exportData.txt');
var doc = app.activeDocument;
doc.activeLayer = doc.artLayers.getByName('Rectangle 1');
var pathItem = doc.pathItems[doc.pathItems.length-1];
var dataStream = "";
for(var subPathIndex = 0;subPathIndex<pathItem.subPathItems.length;subPathIndex++){
for(var pointIndex = 0;pointIndex<pathItem.subPathItems[subPathIndex].pathPoints.length;pointIndex++){
dataStream = dataStream+pathItem.subPathItems[subPathIndex].pathPoints[pointIndex].anchor+'\t';
}
}
dataFile.open('w');
dataFile.write(dataStream);
dataFile.close();
Copy link to clipboard
Copied
Thanks for the reply!
I have a problem with that script, it's spitting out way wrong coordinates:.
-172743.763692396,-8844.11786544597
-86003.376935138,-8844.11786544597
-86003.376935138,23811.086560816
172743.763692396,23811.086560816
Even if I ignore what's after the decimal point, they go well beyond the cm coordinates I have, which range from -8192 to 8192. I've done the rectangle as a path.
Also, is it possible to export the coordinates of multiple layers, seperated by the layer name? Or to automatically grab the layer name of the selected layer that's different than 'Rectangle 1', at least?
Thanks again!
Copy link to clipboard
Copied
Try changing your Photoshop current ruler units to pixels.
// save Photoshop settings local variables
var orig_ruler_units = app.preferences.rulerUnits;
// Set Photoshot behavior
app.preferences.rulerUnits = Units.PIXELS; // Set the ruler units to PIXELS
var dataFile = new File('~/desktop/exportData.txt');
var doc = app.activeDocument;
doc.activeLayer = doc.artLayers.getByName('Rectangle 1');
var pathItem = doc.pathItems[doc.pathItems.length-1];
var dataStream = "";
for(var subPathIndex = 0;subPathIndex<pathItem.subPathItems.length;subPathIndex++){
for(var pointIndex = 0;pointIndex<pathItem.subPathItems[subPathIndex].pathPoints.length;pointIndex++){
dataStream = dataStream+pathItem.subPathItems[subPathIndex].pathPoints[pointIndex].anchor+'\t';
}
}
dataFile.open('w');
dataFile.write(dataStream);
dataFile.close();
// restore Photoshop settings
app.preferences.rulerUnits = orig_ruler_units; // Reset units to original settings
Copy link to clipboard
Copied
Can't yuo use
Export > Paths to Illustrator?
The image has 1000 x 1000 Pixels. The path starts and ends at 500,500.
The numerical values are not integer pixel coordinates but somewhat rounded.
The path in the image is not stroked (for clean information). It's a screenshot
of the unstroked path as shown in Photoshop.
Best regards --Gernot Hoffmann
Text file :
%!PS-Adobe-2.0
%%Creator: Adobe Photoshop(TM) Pen Path Export 7.0
%%Title: (Path.ai)
%%DocumentProcSets: Adobe_Illustrator_1.1 0 0
%%ColorUsage: Black&White
%%BoundingBox: 0 0 1000 1000
%%HiResBoundingBox: 0 0 1000 1000
%AI3_Cropmarks: 0 0 1000 1000
%%DocumentPreview: None
%%EndComments
%%EndProlog
%%BeginSetup
Adobe_Illustrator_1.1 begin
n
%%EndSetup
0.0 0.0 0.0 1.0 k
0 i 0 J 0 j 1 w 4 M []0 d
%%Note:
500.7495 499.2504 m
500.7495 899.5502 l
800.5996 899.5502 l
800.5996 100.4497 l
500.7495 499.2504 l
n
500.7495 499.2504 m
500.7495 899.5502 l
800.5996 899.5502 l
800.5996 100.4497 l
500.7495 499.2504 l
n
%%Trailer
%%EOF
Copy link to clipboard
Copied
I tried, sadly I get this error:
"The document is too big for the coordinate space of illustrator."
The problem is, in order to get the correct coordinates I need for the game map, I need to have a 16384x16384 sized image in photoshop with a pixel per cm of 1, which makes the document 270mb big.
Or is there another way to get coordinates of that size?
Maybe Photoshop isn't the right software for it, but I can't find anything else and I can do it manually in PS, it's just really slow, even if I could record mouse clicks based on the 16384x16384 image coordinates, that could work, but yeah.
Well even if I do it purely in pixels and not cm, including the ruler, I still have the same problem.
__________________________
@JJMack, oh wow, that did the trick, beautiful. Is there any way to not limit it to a specific layer name? So it just chooses the active layer and exports the layer name too? Of to export multiple layer coordinates accompanied with their name?
This is a longshot, but it also wouldn't be possible to either create a new .txt file every time you run the script, besides overwriting the one it made the previous time, right? I can do a workaround with a file copying script, so it's not that big of a deal. Of course the most ideal would be to ADD into the same .txt, without replacing what you previously exported, but I doubt that's possible based on the scripts I've looked at.
Thanks so much!
Copy link to clipboard
Copied
Jusr read the script. Its creating a new file with a fixed name. You can change that to whatever you desire to do.
The script is designed to process one layer by name you can change that. You can loop through all layers looking name or types of layers or layer with path the process should be designed for your documents design.
Copy link to clipboard
Copied
Thanks for the fast reply, I put in this now:
for(var c =0; c<doc.layers.length;c++){
doc.activeLayer= doc.layers
; }
Instead of
doc.activeLayer = doc.artLayers.getByName('Rectangle 1');
It works fine now with multiple layers, but how do I make it so the coordinates get labled by layer in the .txt? With what I changed, it just puts the second layer coordinates right after the first, making it hard to tell the two apart.
To show an example of what I mean.
It shows it like this:
-4821,1859 -1259,-1187 -899,1907 -2782,5014 1487,660 2447,-2003 5481,-2147 5362,3383 2039,2687
What I'd like, is for them to be shown somewhat like this, if layer 1 is called "Layer 1" and layer 2 is called "Layer 2" (as an example):
Layer 1
-4821,1859 -1259,-1187 -899,1907 -2782,5014
Layer 2
1487,660 2447,-2003 5481,-2147 5362,3383 2039,2687
Is that possible?
Basically so it reads the Layer name, whatever it might be, and then exports it in front of, or a line above the coordinates, then seperates the layer coordinates with an [Enter] or two.
Copy link to clipboard
Copied
In the layer loop add a line to output the layer name
dataStream = dataStream+doc.activeLayer.name+'\r';
At the end of the path loop add a line for the break after the point data
dataStream = dataStream+'\r';
And sorry I missed you wanted the output in pixels. Because you said you set up the doc to have 1cm per pixel I thought you would have had the ruler set to cm and would want the values in cm
Copy link to clipboard
Copied
Don't appologize, I was stuck on cm because I thought there wasn't another way, I only figured out after JJMack mentioned it, that it's possible purely by pixels.
First time working with coordinates, I'm in total new territory.
The above works great, except now I've stumbled across 2 new problems, sorry to make it so complicated!
What I have now, slightly tweaked what you gave me:
var dataFile = new File('~/desktop/exportData.txt');
var doc = app.activeDocument;
for(var c =0; c<doc.layers.length;c++){
doc.activeLayer= doc.layers
; }
var pathItem = doc.pathItems[doc.pathItems.length-1];
var dataStream = "";
for(var subPathIndex = 0;subPathIndex<pathItem.subPathItems.length;subPathIndex++){
for(var pointIndex = 0;pointIndex<pathItem.subPathItems[subPathIndex].pathPoints.length;pointIndex++){
dataStream = dataStream+doc.activeLayer.name+'\t';
dataStream = dataStream+pathItem.subPathItems[subPathIndex].pathPoints[pointIndex].anchor+'\t'+'\r';
dataStream = dataStream+'\r';
}
}
dataFile.open('w');
dataFile.write(dataStream);
dataFile.close();
But this outputs this:
Background 4222,0
Background 2963,-3550
Background 4330,-4210
Background 6450.3937,-2459
Background 6141,2387
Background 4834,2891
Background 3970,924
Which made me realize, that the paths aren't bound to a layer (It's been a while since I've used paths), so it'll just use the Background layer. There is no way around that, right? Since this script only targets layers, it'll ignore path names, which brings me to another question, is it possible to use the same thing, only for saved paths? So if you had 2 paths, one named P1 and the other P2, that it would display it like:
P1 4222,0
P1 2963,-3550
P1 4330,-4210
P1 6450.3937,-2459
P2 6141,2387
P2 4834,2891
P2 3970,924
And the other thing, because I'm using a loop now, which basically repeats the \r after ever coordinate, there isn't a way to collect all coordinates and display them in a chain, basically, and then using the \r after all the coordinates for one path is exported, before it moves on to the next path, or? Basically like the post previous to this, except with paths, instead of layers.
Thank you guys so much for helping me though, would been completely lost without it.
Copy link to clipboard
Copied
I'm sure you can reference the path names also, but I'm not on a computer with PS to check. Rather than storing the data the way you're doing it. You should push the info to an array: Then you can later loop through the array to extract just the coordinates and display them however you want.
Copy link to clipboard
Copied
Thanks for the reply!
Do you happen to know the commands off hand? Or is there a list of all possible commands? I'm a complete newb at this.
Copy link to clipboard
Copied
You can reference pahs by name - app.activedocument.pathItems.getByName('my path');
You can reference by index( the order in the paths panel ) - app.activedocument.pathItems[2];
The code I posted selected the shape layer because that is the only way to access the path in the vector mask. If you set the doc up so that everything is in normal paths then you don't need to loop the layers. You loop the paths.
If you want to loop the paths change part that outputs the layer name to output the pathItmem name.
Move the line
dataStream = dataStream+'\r';
to outside the loop. You have in inside so it is putting a line break between each path point
Copy link to clipboard
Copied
Thanks for your reply!
I've tried several ways to switch the layer commands to path commands, but nothing is working. Ugh, I hate feeling so useless, lol. I've tried googling too, but I can't find the right thing. I seriously need to spend some time learning scripts from the ground up, when I find some free time.
But how would I switch it? I'm assuming I need to change the parts in bold:
var dataFile = new File('~/desktop/exportData.txt');
var doc = app.activeDocument; // Does the app.activedocument.pathItems[2] go here?
for(var c =0; c<doc.layers.length;c++){
doc.activeLayer= doc.layers
; }
var pathItem = doc.pathItems[doc.pathItems.length-1];
var dataStream = "";
dataStream = dataStream+doc.activeLayer.name+'\t';
for(var subPathIndex = 0;subPathIndex<pathItem.subPathItems.length;subPathIndex++){
for(var pointIndex = 0;pointIndex<pathItem.subPathItems[subPathIndex].pathPoints.length;pointIndex++){
dataStream = dataStream+pathItem.subPathItems[subPathIndex].pathPoints[pointIndex].anchor+'\t';
}
}
dataFile.open('w');
dataFile.write(dataStream);
dataStream = dataStream+'\r';
dataFile.close();
And thank you so much for the comment about the 'dataStream+'\r', worked perfect when I moved it outside and the ' dataStream = dataStream+doc.activeLayer.name+'\t';' out of the for function.
Sorry that this keeps dragging on, it's near exactly what I want, also sorry for the earlier cofusion on what I wanted.
Copy link to clipboard
Copied
var dataFile = new File('~/desktop/exportData.txt');
var doc = app.activeDocument;
var dataStream = "";
// loop the paths in the document
for(var pathIndex =0; pathIndex<doc.pathItems.length;pathIndex++){
var pathItem = doc.pathItems[pathIndex];
// for every path output the name
dataStream = dataStream+pathItem.name+'\t';
for(var subPathIndex = 0;subPathIndex<pathItem.subPathItems.length;subPathIndex++){
for(var pointIndex = 0;pointIndex<pathItem.subPathItems[subPathIndex].pathPoints.length;pointIndex++){
// for every pathPoint output the anchor position
dataStream = dataStream+pathItem.subPathItems[subPathIndex].pathPoints[pointIndex].anchor+'\t';
}
}
// before starting the next loop add a line break
dataStream = dataStream+'\r';
}
// now that all the paths have been collected write the info to the file
dataFile.open('w');
dataFile.write(dataStream);
dataFile.close();
Copy link to clipboard
Copied
Oh man, I love you.
Can't thank you enough, I was totally in the deep woods. Seriously, this saves me so much time.
Certainly gonna learn scripting from the ground up as soon as I find some time to avoid being in this situation again.