Skip to main content
thomasm14148215
Participant
July 2, 2024
Answered

Script to convert x, y coordinates to photoshop counts?

  • July 2, 2024
  • 3 replies
  • 495 views

I'm working on a project that has been using photoshop to annotate features using the count tool.  I've found some routines to take selected points and export them as a .csv file for analysis...   For example, the scripts shown here: https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-export-coordinates-x-y-in-pixel/td-p/12558105.

 

However, I am hoping to find a way to do the opposite:  I want to turn a .csv of pixel x-y coordinates into count objects in a photoshop document.  Is there a way one could do that? 

 

[why you ask?  I've found an automated routine that works about 95% of the time to pick up a subset of the features I'm counting, and I'd like to be able to run that, and export its values back into photoshop to fix and "tweak" the remaining 5% of features. ]

This topic has been closed for replies.
Correct answer Stephen Marsh

@thomasm14148215 

 

You can try this script:

 

/*
Plot Count Tool Co-ordinates From CSV.jsx
v1.0 2nd July 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-convert-x-y-coordinates-to-photoshop-counts/td-p/14713755
Note: There should be no header row - only X,Y pixel coordinates per row!
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/csv-data-to-colour-pixels/m-p/14358713
*/

#target photoshop

app.activeDocument.suspendHistory ("Count from CSV...", "main()");

function main() {

    if (app.documents.length) {

        // Get and set the ruler units
        var origRulerUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        // Select and validate the CSV file
        var csvFile = File.openDialog("Select the CSV file:");
        if (csvFile.exists) {
            if (csvFile.length > 0) {

                // Hide panels
                app.togglePalettes();

                // CSV open, read & close
                csvFile.open("r");
                var theData = csvFile.read();
                csvFile.close();

                // CSV to array
                var theDataArray = parseCSV(theData);

                // Loop over the CSV data
                for (var i = 0; i < theDataArray.length; i++) {
                    var csvValueX = theDataArray[i].toString().split(',')[0];
                    var csvValueY = theDataArray[i].toString().split(',')[1];
                    csvValueXcleaned = parseInt(csvValueX);
                    csvValueYcleaned = parseInt(csvValueY);
                    // Debugger
                    $.writeln(csvValueXcleaned);
                    $.writeln(csvValueYcleaned);

                    // Plot the count tool from the CSV coordinates
                    theCountTool(csvValueXcleaned, csvValueYcleaned)
                }

                // Restore the original ruler units
                app.preferences.rulerUnits = origRulerUnits;

                // End of script
                app.togglePalettes();
                app.beep();
                // Select the count tool
                (r = new ActionReference()).putClass(stringIDToTypeID('countTool'));
                (d = new ActionDescriptor()).putReference(stringIDToTypeID('target'), r);
                executeAction(stringIDToTypeID('select'), d, DialogModes.NO);

            } else {
                app.beep();
                alert('The CSV file is blank!');
            }
        }

    } else {
        alert('You must have a document open!');
    }

}


///// FUNCTIONS /////

function theCountTool(theX, theY) {
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    descriptor.putDouble(s2t("x"), theX);
    descriptor.putDouble(s2t("y"), theY);
    executeAction(s2t("countAdd"), descriptor, DialogModes.NO);
}

function parseCSV(theData, delimiter) {
    /* 
    Courtesy of William Campbell
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/does-any\.$one-have-a-script-that-utilizes-a-csv-to-create-text-layers/m-p/13117458
    */

    // theData: String = contents of a CSV csvFile
    // delimiter: character that separates columns
    //            undefined defaults to comma
    // Returns: Array [[String row, String column]]

    var c = ""; // Character at index
    var d = delimiter || ","; // Default to comma
    var endIndex = theData.length;
    var index = 0;
    var maxIndex = endIndex - 1;
    var q = false; // "Are we in quotes?"
    var result = []; // Array of rows (array of column arrays)
    var row = []; // Array of columns
    var v = ""; // Column value

    while (index < endIndex) {
        c = theData[index];
        if (q) { // In quotes
            if (c == "\"") {
                // Found quote; look ahead for another
                if (index < maxIndex && theData[index + 1] == "\"") {
                    // Found another quote means escaped
                    // Increment and add to column value
                    index++;
                    v += c;
                } else {
                    // Next character not a quote; last quote not escaped
                    q = !q; // Toggle "Are we in quotes?"
                }
            } else {
                // Add character to column value
                v += c;
            }
        } else { // Not in quotes
            if (c == "\"") {
                // Found quote
                q = !q; // Toggle "Are we in quotes?"
            } else if (c == "\n" || c == "\r") {
                // Reached end of line
                // Test for CRLF
                if (c == "\r" && index < maxIndex) {
                    if (theData[index + 1] == "\n") {
                        // Skip trailing newline
                        index++;
                    }
                }
                // Column and row complete
                row.push(v);
                v = "";
                // Add row to result if first row or length matches first row
                if (result.length === 0 || row.length == result[0].length) {
                    result.push(row);
                }
                row = [];
            } else if (c == d) {
                // Found comma; column complete
                row.push(v);
                v = "";
            } else {
                // Add character to column value
                v += c;
            }
        }
        if (index == maxIndex) {
            // Reached end of theData; flush
            if (v.length || c == d) {
                row.push(v);
            }
            // Add row to result if length matches first row
            if (row.length == result[0].length) {
                result.push(row);
            }
            break;
        }
        index++;
    }
    return result;
}

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

3 replies

Participant
July 2, 2024

 

javascript

function loadCSV(filePath) {
var file = new File(filePath);
file.open('r');
var content = file.read();
file.close();
return content;
}

function parseCSV(content) {
var lines = content.split('\n');
var points = [];
for (var i = 0; i < lines.length; i++) {
var coords = lines[i].trim().split(',');
if (coords.length == 2) {
var x = parseFloat(coords[0]);
var y = parseFloat(coords[1]);
if (!isNaN(x) && !isNaN(y)) {
points.push({ x: x, y: y });
}
}
}
return points;
}

function addCountToolPoints(points) {
var doc = app.activeDocument;
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putClass(charIDToTypeID('PbTl'));
desc.putReference(charIDToTypeID('null'), ref);
var list = new ActionList();
for (var i = 0; i < points.length; i++) {
var point = new ActionDescriptor();
point.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), points[i].x);
point.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), points[i].y);
list.putObject(charIDToTypeID('Pnt '), point);
}
desc.putList(charIDToTypeID('Pts '), list);
executeAction(charIDToTypeID('Mk '), desc, DialogModes.NO);
}

function main() {
var filePath = File.openDialog('Select CSV file');
if (filePath) {
var content = loadCSV(filePath);
var points = parseCSV(content);
addCountToolPoints(points);
alert('Count points added successfully.');
} else {
alert('No file selected.');
}
}

main();


```

Save this script with a `.jsx` extension (e.g., `importCounts.jsx`). To run the script in Photoshop, open Photoshop, go to `File > Scripts > Browse`, and select the saved `.jsx` file. This script will prompt you to select a CSV file, parse its x, y coordinates, and add count tool points to the active Photoshop document based on these coordinates.

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
July 2, 2024

@thomasm14148215 

 

You can try this script:

 

/*
Plot Count Tool Co-ordinates From CSV.jsx
v1.0 2nd July 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-convert-x-y-coordinates-to-photoshop-counts/td-p/14713755
Note: There should be no header row - only X,Y pixel coordinates per row!
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/csv-data-to-colour-pixels/m-p/14358713
*/

#target photoshop

app.activeDocument.suspendHistory ("Count from CSV...", "main()");

function main() {

    if (app.documents.length) {

        // Get and set the ruler units
        var origRulerUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        // Select and validate the CSV file
        var csvFile = File.openDialog("Select the CSV file:");
        if (csvFile.exists) {
            if (csvFile.length > 0) {

                // Hide panels
                app.togglePalettes();

                // CSV open, read & close
                csvFile.open("r");
                var theData = csvFile.read();
                csvFile.close();

                // CSV to array
                var theDataArray = parseCSV(theData);

                // Loop over the CSV data
                for (var i = 0; i < theDataArray.length; i++) {
                    var csvValueX = theDataArray[i].toString().split(',')[0];
                    var csvValueY = theDataArray[i].toString().split(',')[1];
                    csvValueXcleaned = parseInt(csvValueX);
                    csvValueYcleaned = parseInt(csvValueY);
                    // Debugger
                    $.writeln(csvValueXcleaned);
                    $.writeln(csvValueYcleaned);

                    // Plot the count tool from the CSV coordinates
                    theCountTool(csvValueXcleaned, csvValueYcleaned)
                }

                // Restore the original ruler units
                app.preferences.rulerUnits = origRulerUnits;

                // End of script
                app.togglePalettes();
                app.beep();
                // Select the count tool
                (r = new ActionReference()).putClass(stringIDToTypeID('countTool'));
                (d = new ActionDescriptor()).putReference(stringIDToTypeID('target'), r);
                executeAction(stringIDToTypeID('select'), d, DialogModes.NO);

            } else {
                app.beep();
                alert('The CSV file is blank!');
            }
        }

    } else {
        alert('You must have a document open!');
    }

}


///// FUNCTIONS /////

function theCountTool(theX, theY) {
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    descriptor.putDouble(s2t("x"), theX);
    descriptor.putDouble(s2t("y"), theY);
    executeAction(s2t("countAdd"), descriptor, DialogModes.NO);
}

function parseCSV(theData, delimiter) {
    /* 
    Courtesy of William Campbell
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/does-any\.$one-have-a-script-that-utilizes-a-csv-to-create-text-layers/m-p/13117458
    */

    // theData: String = contents of a CSV csvFile
    // delimiter: character that separates columns
    //            undefined defaults to comma
    // Returns: Array [[String row, String column]]

    var c = ""; // Character at index
    var d = delimiter || ","; // Default to comma
    var endIndex = theData.length;
    var index = 0;
    var maxIndex = endIndex - 1;
    var q = false; // "Are we in quotes?"
    var result = []; // Array of rows (array of column arrays)
    var row = []; // Array of columns
    var v = ""; // Column value

    while (index < endIndex) {
        c = theData[index];
        if (q) { // In quotes
            if (c == "\"") {
                // Found quote; look ahead for another
                if (index < maxIndex && theData[index + 1] == "\"") {
                    // Found another quote means escaped
                    // Increment and add to column value
                    index++;
                    v += c;
                } else {
                    // Next character not a quote; last quote not escaped
                    q = !q; // Toggle "Are we in quotes?"
                }
            } else {
                // Add character to column value
                v += c;
            }
        } else { // Not in quotes
            if (c == "\"") {
                // Found quote
                q = !q; // Toggle "Are we in quotes?"
            } else if (c == "\n" || c == "\r") {
                // Reached end of line
                // Test for CRLF
                if (c == "\r" && index < maxIndex) {
                    if (theData[index + 1] == "\n") {
                        // Skip trailing newline
                        index++;
                    }
                }
                // Column and row complete
                row.push(v);
                v = "";
                // Add row to result if first row or length matches first row
                if (result.length === 0 || row.length == result[0].length) {
                    result.push(row);
                }
                row = [];
            } else if (c == d) {
                // Found comma; column complete
                row.push(v);
                v = "";
            } else {
                // Add character to column value
                v += c;
            }
        }
        if (index == maxIndex) {
            // Reached end of theData; flush
            if (v.length || c == d) {
                row.push(v);
            }
            // Add row to result if length matches first row
            if (row.length == result[0].length) {
                result.push(row);
            }
            break;
        }
        index++;
    }
    return result;
}

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

thomasm14148215
Participant
July 4, 2024

This worked for me!  Thank you for the help!

Stephen Marsh
Community Expert
Community Expert
July 4, 2024
quote

This worked for me!  Thank you for the help!


By @thomasm14148215

 

You're welcome, thank you for coming back to comment and marking my answer as a correct answer!

Stephen Marsh
Community Expert
Community Expert
July 2, 2024

Yes, this is doable, however, a script would need to be found/altered or created for this task.