Skip to main content
Participating Frequently
November 6, 2021
Question

Create one-color jpgs from csv file

  • November 6, 2021
  • 6 replies
  • 2925 views

Hello,

 

I am looking for a solution to solve following problem.

 

I would like to create 1000 .jpgs. Each of these .jpgs in srgb color space consists of just one single color. All the color variations are saved in a .csv file as hex code. Has anyone an idea how these .jpgs could be generated? It would also would be great if the final filename of the jpeg couls be the hexcode.

 

Thank you for your help,

Seb

This topic has been closed for replies.

6 replies

Legend
November 16, 2021

I thought when you said "JPEG" that we would end up having to explain that JPEG is a lossy format. This means you MUST EXPECT colour changes in almost every file. This is how JPEG is designed to work, it is not a fault. Colours may not be the same across the whole image, and will usually change in each resave. The quality settings may alter the value but there is no way to turn off how JPEG is supposed to work. 

rob day
Community Expert
Community Expert
November 16, 2021

If the reason for JPEG is the need for compression, then a better option might be to export an indexed, 2-color PNG. The 8-bit PNG exports as 300 bytes vs. 500+KB for JPEG, and HEX values are correct. This exports an 8-bit PNG:

 

var tf = File.openDialog("Select a text file to read");
tf.open("r");
var txt = tf.read();
var hxList = txt.split("\n")

var f = Folder.selectDialog("Select a folder for the Saved JPEGs");

//the save for web PNG Options 
var so = new ExportOptionsSaveForWeb();
so.format = SaveDocumentType.PNG;
so.PNG8 = true;
so.colors = 2;

app.preferences.rulerUnits = Units.INCHES;

var w = 5;
var h = 7;
var r = 72;

var doc, cn, fc;


for (var i = 0; i < hxList.length; i++){
    cn = hxList[i]
    fc = makeRGB(hxList[i].toString());
    doc = app.documents.add(w, h, r, cn);
    doc.selection.fill(fc);
    doc.exportDocument(new File(f + "/" + cn + ".png"), ExportType.SAVEFORWEB, so);
    doc.close(SaveOptions.DONOTSAVECHANGES); 
};   
 


/**
* Makes and returns an RGB color 
*  a HEX string
*  returns an RGBColor 
* 
*/	

function makeRGB(a){
    var colorobj = new RGBColor()
    colorobj.hexValue = a;
    return colorobj;
};
sesam44Author
Participating Frequently
November 21, 2021

Thank you for your help! I just tried the script and when I use 8-bit PNGs there are color shifts. As long as I use 24-bit PNGs no color shifts accure. I also adjustet some parameters:

//the save for web PNG Options 
var so = new ExportOptionsSaveForWeb();
so.format = SaveDocumentType.PNG;
so.PNG24 = true;
app.preferences.rulerUnits = Units.PIXELS;

var w = 1080;
var h = 1080;
var r = 96;

 As a result I get a 2kb PNG with no colorshifts.

Do you get the same results using the adjusted script or am I missing something which can cause some problems?

rob day
Community Expert
Community Expert
November 6, 2021

If the hex list could be a simple text file, getting the values would be easier—you wouldn’t have to parse columns and rows.

 

If the text file could be the values separated by a return:

 

 

Then this would work:

 

 

var tf = File.openDialog("Select a text file to read");
tf.open("r");
var txt = tf.read();
var hxList = txt.split("\n")

var f = Folder.selectDialog("Select a folder for the Saved JPEGs");
var so = new JPEGSaveOptions();

app.preferences.rulerUnits = Units.INCHES;

var w = 5;
var h = 7;
var r = 72;

var doc, cn, fc;


for (var i = 0; i < hxList.length; i++){
    cn = hxList[i]
    fc = makeRGB(hxList[i].toString());
    doc = app.documents.add(w, h, r, cn);
    doc.selection.fill(fc);
    doc.saveAs(new File(f + "/" + cn + ".jpg"), so);
    doc.close();
};   
 


/**
* Makes and returns an RGB color 
*  a HEX string
*  returns an RGBColor 
* 
*/	

function makeRGB(a){
    var colorobj = new RGBColor()
    colorobj.hexValue = a;
    return colorobj;
};

 

 

sesam44Author
Participating Frequently
November 15, 2021

Thank you so much for your help!

This script would be perfect, unfourtanatly the colors in the text document and in the files don´t match.
If my input value is #010093 my output color is #020092.
Has anyone an idea how this can happen?

Legend
November 15, 2021

Most likely the problem is that JPEG is not the best format for storing accurate color values. JPEG uses the YCbCr color space, i.e. all colors of your image are converted into it before saving. Since JPEG was originally conceived as a lossy format, due to limited computational accuracy, not all colors can be converted correctly.

For example, if we perform operations without rounding, then after converting RGB-> YCbCr-> RGB:

 

/*
	BT.601	BT.709	BT.2020
a	0.299	0.2126	0.2627
b	0.587	0.7152	0.6780
c	0.114	0.0722	0.0593
d	1.772	1.8556	1.8814
e	1.402	1.5748	1.4747
*/

makeRGB('010093')

function makeRGB(a) {
    var colorobj = new RGBColor();
    colorobj.hexValue = a;

    with (colorobj) {
        var Y =0.2627 * red + 0.6780 * green + 0.0593 * blue,
            Cb = (blue - Y) / 1.8814,
            Cr = (red - Y) / 1.4747;

        red = Y + 1.4747 * Cr
        green = Y - (0.2627 * 1.4747 / 0.6780) * Cr - (0.0593 * 1.8814 / 0.6780) * Cb
        blue = Y + 1.8814 * Cb

    }
$.writeln (colorobj.hexValue)
};

 

we get the same color:

 

Result: 010093

 

 

But if we round up the values during conversion:

 

/*
	BT.601	BT.709	BT.2020
a	0.299	0.2126	0.2627
b	0.587	0.7152	0.6780
c	0.114	0.0722	0.0593
d	1.772	1.8556	1.8814
e	1.402	1.5748	1.4747
*/

makeRGB('010093')

function makeRGB(a) {
    var colorobj = new RGBColor();
    colorobj.hexValue = a;

    with (colorobj) {
        var Y = Math.round(0.2627 * red + 0.6780 * green + 0.0593 * blue),
            Cb = Math.round((blue - Y) / 1.8814),
            Cr = Math.round((red - Y) / 1.4747);

        red = Math.round(Y + 1.4747 * Cr)
        green = Math.round(Y - (0.2627 * 1.4747 / 0.6780) * Cr - (0.0593 * 1.8814 / 0.6780) * Cb)
        blue = Math.round(Y + 1.8814 * Cb)

    }
$.writeln (colorobj.hexValue)
};

 

we get exactly the color that you see after opening the file:

 

Result: 020092

 

We could assume that only Photoshop does this, but no, it looks like rounding is spelled out in the standard. I generated a tiff file with color # 010093 and tried converting it in various programs (including ImageMagik, which is famous for its exact adherence to all standards) - in all cases I got a JPG with color # 020092

 

So, I recommend using a different image format.

Legend
November 6, 2021

A similar problem was discussed in this thread. True, the situation there was a little more complicated, but the script will work fine in your case (the only thing is, you need to carefully read how to prepare a file layout and rewrite the save function in jpg)

 

Fill shape colour by adding DMC number 

Kukurykus
Legend
November 7, 2021

Loll, bad luck for me - you were this time faster to link the user to your own post 😄

rob day
Community Expert
Community Expert
November 6, 2021

It should be scriptable. Here’s a simple example where 3 documents are created from a list of hex values—var hxList. I haven’t included a save as to JPEG, but that would be easy, and a script could also open a CSV to get the list:

 

app.preferences.rulerUnits = Units.INCHES;


var hxList = ["60b7ba", "ff0000", "be6fb2"]
var w = 5;
var h = 7;
var r = 72;
var doc, cn, fc;


for (var i = 0; i < hxList.length; i++){
    cn = hxList[i]
    fc = makeRGB(hxList[i]);
    doc = app.documents.add(w, h, r, cn);
    doc.selection.fill(fc);
};   
 


/**
* Makes and returns an HEX color 
* @9397041 hex string
* @Returns a RGBColor 
* 
*/	

function makeRGB(a){
    var colorobj = new RGBColor()
    colorobj.hexValue = a;
    return colorobj;
};

 

 

 

sesam44Author
Participating Frequently
November 6, 2021

thank you so much for your time and help!
I will try to include the save as jpg command!
how would the script to open a csv document look like - just interested if this would make things easier and more accesible for people who are not into scripting and coding.

Thank you very much for your help!

JJMack
Community Expert
Community Expert
November 6, 2021

You can read and write files with javascript. You should be able to read your CSV file in a Photoshop script.

This Photoshop will read its temp files in your system  temp space and display its content.  If the File does not exists it will create the file when you run it.  So if you  run the script it will both write and read the file.

#target photoshop
app.bringToFront();



//Set First Time Defaults here
var dfltCpys = 12;	// default number of copies including the original
var dfltPos = 4;	// default Middle Center
//End Defaults

var Prefs ={}; //Object to hold preferences.
var prefsFile = File(Folder.temp + "/RotateLayerAboutPreferences.dat");
//If preferences do not exit use defaults
if(!prefsFile.exists){
	alert("Create Preference File");
	Prefs.Cpys  = dfltCpys;
	Prefs.Pos  = dfltPos;
	prefsFile.open('w');
	prefsFile.write(Prefs.toSource());
	prefsFile.close();
	}
else{//Preferences exist so open them
	alert("Read Preference File");
	prefsFile.open('r');
	Prefs = eval(prefsFile.read());
	prefsFile.close();
    }

alert(Prefs.Cpys + " , " + Prefs.Pos);
JJMack
Chris 486
Community Expert
Community Expert
November 6, 2021

Hi sesam44,

 

I'm not aware of an automated way to do this. I think you will have to have to input your data manually from the hexcode photohsop gives you. You mention that this is a workaround for for something you are already trying to do. Have you posted your original goal for this yet? Maybe someone in the comunity can get creative with finding additional workarounds?

 

 

I was only thinking in the automations menu before I re-read the post and saw the below; which is a great example! Time for another coffee for me for answering more posts!

sesam44Author
Participating Frequently
November 6, 2021

Thank you for your time and answering this post!

JJMack
Community Expert
Community Expert
November 6, 2021

How do you convert the hex data in the csv file into a digital image that is displayable on your display?

JJMack
sesam44Author
Participating Frequently
November 6, 2021

Thank you for your time!

 

Sometimes I am working in photoshop with variables and now I am looking for a workaround, because unfortunately there ia no way to define single values of adjustment layers as a variable. 

 

The easiest way would be if I could set the color value of a solid color layer as a variable and import the .csv file. Maybe there are some other programs offering this option and photoshop is the wrong software in this case?

 

Another way could be to have a textlayer defined as variable which would be the hex-value. In the first step there could be generated .psd files with changing text and in the next step with the help of a script or action??? (not sure if this work) photoshop couls copy the textlayer into the clipboard and use as reference while creating a solid color.

 

Maybe you have another idea to solve this problem.