Skip to main content
Rachelle_Banker
Participating Frequently
September 9, 2020
Answered

Random pixels placement within a colored area

  • September 9, 2020
  • 6 replies
  • 1881 views

Hello,

I am working on a project where a certain color area has to be filled with random pixels within certain color shades range. For example, a red color area has to be filled with a certain range of shade of green pixels randomly placed. I am doing this manually and it is very time consuming task.

 

Is it possible that part being done with a script? Scripting in Photoshop is a bit discouraging for me and learning is a good option. If possible, will someone show me with an example on how to do it?

 

Thanks,

Rachelle

This topic has been closed for replies.
Correct answer rob day

where a certain color area has to be filled with random pixels within certain color shades range

 

How many pixels are in your selection? If you are doing it manually it can’t be that many right?

 

There is the selection.translateBoundary (x, y) that could move a 1x1 pixel selection. On my not too fast machine it takes about 10 sec to move and fill a selection 100 times.

 

 

 

#target photoshop
var docRef = app.activeDocument;
var bnds = docRef.selection.bounds
var sw = bnds[2]-bnds[0];
var sh = bnds[3]-bnds[1];

//selects the upper-left pixel of the selection
docRef.selection.select([[bnds[0], bnds[1]], [bnds[0]+1, bnds[1]], [bnds[0]+1, bnds[1]+1], [bnds[0], bnds[1]+1]] , SelectionType.REPLACE, 0, false);


var xc = 0;
var yc = 0
for (var i = 0; i < sw*sh; i++){
    if(xc<sw){
        docRef.selection.select([[bnds[0], bnds[1]], [bnds[0]+1, bnds[1]], [bnds[0]+1, bnds[1]+1], [bnds[0], bnds[1]+1]] , SelectionType.REPLACE, 0, false);
        docRef.selection.translateBoundary (xc, yc);
    }else{
        xc = 0;
        yc++;
        docRef.selection.select([[bnds[0], bnds[1]], [bnds[0]+1, bnds[1]], [bnds[0]+1, bnds[1]+1], [bnds[0], bnds[1]+1]] , SelectionType.REPLACE, 0, false);
        docRef.selection.translateBoundary (xc, yc)
    }
    docRef.selection.fill(randomHSB(200, 220));
    xc++
};   




/**
* returns a random HSB color 
* @returns a SolidColor 
* 
*/
function randomHSB(hmin, hmax){
    colorobj = new SolidColor()
    colorobj.hsb.hue = getRndInteger(hmin, hmax);
    colorobj.hsb.saturation = getRndInteger(10, 100);
    colorobj.hsb.brightness = getRndInteger(30, 100); 
    return colorobj;
};

/**
* @ returns a random number between min and max
* 
*/
function getRndInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1) ) + min;
}; 	

 

 

 

6 replies

Legend
September 16, 2020
Here is an interesting topic about changing individual (or all) pixels.
https://community.adobe.com/t5/photoshop/get-index-of-each-pixel/m-p/10022899?page=1

Note: scripts are most likely not working, because when transferring from the old forum to the new one, at least the expressions [i] were gone. You need to manually place them where necessary.
 
Rachelle_Banker
Participating Frequently
September 17, 2020

Thank you r-bin,

 

This will for certain come in handy

rob day
Community Expert
Community Expert
September 15, 2020

This is 2500 pixels and it took 5min on an old iMac

 

rob day
Community Expert
rob dayCommunity ExpertCorrect answer
Community Expert
September 15, 2020

where a certain color area has to be filled with random pixels within certain color shades range

 

How many pixels are in your selection? If you are doing it manually it can’t be that many right?

 

There is the selection.translateBoundary (x, y) that could move a 1x1 pixel selection. On my not too fast machine it takes about 10 sec to move and fill a selection 100 times.

 

 

 

#target photoshop
var docRef = app.activeDocument;
var bnds = docRef.selection.bounds
var sw = bnds[2]-bnds[0];
var sh = bnds[3]-bnds[1];

//selects the upper-left pixel of the selection
docRef.selection.select([[bnds[0], bnds[1]], [bnds[0]+1, bnds[1]], [bnds[0]+1, bnds[1]+1], [bnds[0], bnds[1]+1]] , SelectionType.REPLACE, 0, false);


var xc = 0;
var yc = 0
for (var i = 0; i < sw*sh; i++){
    if(xc<sw){
        docRef.selection.select([[bnds[0], bnds[1]], [bnds[0]+1, bnds[1]], [bnds[0]+1, bnds[1]+1], [bnds[0], bnds[1]+1]] , SelectionType.REPLACE, 0, false);
        docRef.selection.translateBoundary (xc, yc);
    }else{
        xc = 0;
        yc++;
        docRef.selection.select([[bnds[0], bnds[1]], [bnds[0]+1, bnds[1]], [bnds[0]+1, bnds[1]+1], [bnds[0], bnds[1]+1]] , SelectionType.REPLACE, 0, false);
        docRef.selection.translateBoundary (xc, yc)
    }
    docRef.selection.fill(randomHSB(200, 220));
    xc++
};   




/**
* returns a random HSB color 
* @returns a SolidColor 
* 
*/
function randomHSB(hmin, hmax){
    colorobj = new SolidColor()
    colorobj.hsb.hue = getRndInteger(hmin, hmax);
    colorobj.hsb.saturation = getRndInteger(10, 100);
    colorobj.hsb.brightness = getRndInteger(30, 100); 
    return colorobj;
};

/**
* @ returns a random number between min and max
* 
*/
function getRndInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1) ) + min;
}; 	

 

 

 

Rachelle_Banker
Participating Frequently
September 17, 2020

Thanks rob day,

Actually there are few hundreds pixels each time, relatively small area. At least I will not be in front of the monitor all the time.

 

It is true that its execution time is slow, i already know that JS is not meant to be used for such procedural works but this script will do a great job.

 

What those bracketed numbres mean? I know they represent arrays, but to what they point? PS scripting guide does not explain it well as I can notice. Any other reference for PS scripting that is better than the original one?

 

Thanks

Chuck Uebele
Community Expert
Community Expert
September 15, 2020

Aside from a script being incredibly slow, you might need to select one color at a time by making a selection. If you ran a script over the whole image and sampled each pixel, it would not only slow the process down, but you might sample one of the already replaced pixels, giving you a false reading as to the color.

Chuck Uebele
Community Expert
Community Expert
September 14, 2020

As r-bin mentioned filling pixel by pixel would take a very long time, even with a script. Also as mentioned more info would help. Are these solid areas of color that you're trying to fill with random different colors?  If so, a selection could be made of each area and a script could run to fill pixels within the selectiom's bounding box, which could speed up the process a bit. You could also try creating a random pixel layer using dissolve blend mode, then use that as a selection to fill an area at one time. 

Rachelle_Banker
Participating Frequently
September 15, 2020

"Are these solid areas of color that you're trying to fill with random different colors?"

Yes, that's it. Script has to know that the area colored, for example, red, has to be filled with random pixels that are in chosen range. It is not a standard noise, it is actully a noise made of pixels within a certain range, for example, a shade of green pixels. Dissolve blend is too generic.

 

 

 

 

JJMack
Community Expert
Community Expert
September 15, 2020

Color area can scattered through you document canvas  like as black an red checker board.   Photoshop can rapidity select the red areas.  So a script  can select the red pixels areas fast, add an empty layer and fill the selection with a patten random pixels that have the colors you want scattered in the red area. The pixels will be in a layer in area over the original red selected area and not destroy your red areas.   You need to design  a process that will give you the results you want.  Chuck is telling you some methods you can use to do you process will we be very long running process if implemented using Photoshop scripting.  A document with a larger canvas may take hours to process.  You can not process millions of pixels in document  pixel by pixel in  reasonable  amount  of time with a Photoshop script.  You need to design a process the has a chance of running is a reasonable amount of time.

JJMack
JJMack
Community Expert
Community Expert
September 9, 2020

In Java Script it is very easy to generate random numbers with in a range. Select an area  around 4px by 4px and fill with color

to keep it them with a shaped area would require you to  add the pixels to own layer keep the randomness to the bounds of the colored selection. then mask the layer to the colored selection area. 

 

 

/**
* @ returns a random number between min and max
* 
*/
function getRndInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1) ) + min;
}; 	

 

 

So knowing the width and height of your  document it would be easy to generate randoen x,y pixel point within an area of your document by limitings ranges of the X and  Y points.

 

The same is true for colors you can set ranges.  For Hue to confine the colors to a  particular range of colors and most likley keep the brightness up  some the avoide blackness. 

 

 

app.backgroundColor = randomHSB(90, 240);
app.foregroundColor = randomHSB(0, 45);

/**
* returns a random HSB color 
* @returns a SolidColor 
* 
*/
function randomHSB(hmin, hmax){
    colorobj = new SolidColor()
    colorobj.hsb.hue = getRndInteger(hmin, hmax);
    colorobj.hsb.saturation = getRndInteger(10, 100);
    colorobj.hsb.brightness = getRndInteger(30, 100); 
    return colorobj;
};

 

 

JJMack
Rachelle_Banker
Participating Frequently
September 13, 2020

Thank you JJMack,

Is it possible to random colorize certain pixel with scripting instead?

Legend
September 13, 2020
Access to individual layer pixels is not available in scripts and actions. You can select a 1x1 pixel area anywhere and fill it with any color. If you have thousands of such pixels, then the procedure will take a very long time.

Not quite sure what you want to do. How do you do your task manually, without scripts?