Random Position, with Options to Scale and Resize

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

roberthpaige

Random Position, with Options to Scale and Resize

Post by roberthpaige »

I was wondering if someone could help me script something like this: http://work.dmonzon.com/genart/genart.html

But in photoshop and use the controls for the selected layers.

Professional AI Audio Generation within Adobe Premiere Pro - Download Free Plugin here

pfaffenbichler

Random Position, with Options to Scale and Resize

Post by pfaffenbichler »

What exactly do you want to achieve?
The animation or just the pseudo-randomized distribution of instances?

And what do you mean by »Scale and Resize«?
pfaffenbichler

Random Position, with Options to Scale and Resize

Post by pfaffenbichler »

Does this help?
Code: Select all// http://ps-scripts.com/bb/viewtopic.php?f=9&t=5478
// randomly distribute instances of selected layers;
// 2013, pfaffenbichler;
// use it at your own risk;
#target photoshop
var checksOut = photoshopCheck();
// do the operation if the check pass;
if (checksOut == true) {
   app.activeDocument.suspendHistory("confetti", "main()");
   };
////// the operation //////
function main() {
//filter for checking if entry is numeric, whole and positive, thanks to xbytor;
wholePosNumberKeystrokeFilter = function() {
   this.text = this.text.replace(",", "");
   this.text = this.text.replace(".", "");
   this.text = this.text.replace("-", "");
   if (this.text.match(/[^\-\.\d]/)) {
      this.text = this.text.replace(/[^\-\.\d]/g, '');
      }
   };
//filter for checking if entry is numeric and positive, thanks to xbytor;
posNumberKeystrokeFilter = function() {
   this.text = this.text.replace(",", ".");
   this.text = this.text.replace("-", "");
   if (this.text.match(/[^\-\.\d]/)) {
      this.text = this.text.replace(/[^\-\.\d]/g, '');
      }
   };
//filter for checking if entry is numeric and between -180 and 180, thanks to xbytor;
degreesKeystrokeFilter = function() {
   this.text = this.text.replace(",", ".");
   if (this.text.match(/[^\-\.\d]/)) {
      this.text = this.text.replace(/[^\-\.\d]/g, '');
      };
   if (this.text < -180) {this.text = -180};
   if (this.text > 180) {this.text = 180};
   };
var myDocument = app.activeDocument;
var myResolution = myDocument.resolution;
// get selected layers;
var theLayers = GetSelectedLayers();
var theNumberOfLayers = theLayers.length;
var originalUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var theWidth = myDocument.width;
var theHeight = myDocument.height;
////////////////////////////////////
var dlg = new Window('dialog', "make copies of selected layers", [500,300,840,500]);
// field for copies;
dlg.copies = dlg.add('panel', [15,15,325,65], 'number of copies');
dlg.copies.number = dlg.copies.add('edittext', [12,12,60,32], Math.round(200 / theNumberOfLayers), {multiline:false});
dlg.copies.numberText = dlg.copies.add('statictext', [65,14,320,32], "instances, amounts to "+String((Math.round(200 / theNumberOfLayers)) * theNumberOfLayers)+" elements", {multiline:false});
dlg.copies.number.onChange = wholePosNumberKeystrokeFilter;
// update test to correct number;
dlg.copies.number.onChange = function () {dlg.copies.numberText.text = "instances, amounts to "+(theNumberOfLayers*Number(this.text))+" elements"};
// field for rotate;
dlg.rotate = dlg.add('panel', [175,75,325,125], 'rotate between ˚');
dlg.rotate.number1 = dlg.rotate.add('edittext', [12,12,60,32], 0, {multiline:false});
dlg.rotate.number2 = dlg.rotate.add('edittext', [75,12,123,32], 0, {multiline:false});
dlg.rotate.number1.onChange = degreesKeystrokeFilter;
dlg.rotate.number2.onChange = degreesKeystrokeFilter;
// field for rescale;
dlg.scale = dlg.add('panel', [15,75,165,125], 'scale between %');
dlg.scale.number1 = dlg.scale.add('edittext', [12,12,50,32], 10, {multiline:false});
dlg.scale.number2 = dlg.scale.add('edittext', [55,12,93,32], 60, {multiline:false});
dlg.scale.flip = dlg.scale.add('checkbox', [100,12,150,32], "flip");
dlg.scale.number1.onChange = posNumberKeystrokeFilter;
dlg.scale.number2.onChange = posNumberKeystrokeFilter;
// buttons for ok, and cancel;
dlg.buttons = dlg.add('panel', [15,135,325,185], '');
dlg.buttons.buildBtn = dlg.buttons.add('button', [13,13,145,33], 'OK', {name:'ok'});
dlg.buttons.cancelBtn = dlg.buttons.add('button', [155,13,290,33], 'Cancel', {name:'cancel'});
// show the dialog;
dlg.center();
var myReturn = dlg.show ();
////////////////////////////////////
if (myReturn == 1) {
   app.togglePalettes();
   var originalResolution = myDocument.resolution;
   myDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);
var time1 = Number(timeString());
// collect the entries;
var theCopies = dlg.copies.number.text;
var theScale1 = Math.min(dlg.scale.number1.text, dlg.scale.number2.text);
var theScale2 = Math.max(dlg.scale.number1.text, dlg.scale.number2.text);
//var theScaleProp = dlg.scale.proportion.value;
var theFlip = dlg.scale.flip.value;
var theRotate1 = Math.min(dlg.rotate.number1.text, dlg.rotate.number2.text);
var theRotate2 = Math.max(dlg.rotate.number1.text, dlg.rotate.number2.text);
// convert to smart objects if not such already;
var theSOs = new Array;
for (var d = theNumberOfLayers - 1; d >= 0; d--) {
   app.activeDocument.activeLayer = theLayers[d];
   var thisLayer = smartify (theLayers[d]);
   theSOs.push ([thisLayer, getLayerId(thisLayer)])
   };
////////////////////////////////////
myDocument.selection.deselect();
// do the transformations;
var copyThis = 0;
for (var n = 0; n < theCopies * theSOs.length; n++) {
$.writeln(n);
// create the copies;
   var theLayer = theSOs[copyThis][0];
   if (theSOs.length > 1) {
      copyThis++
      if (copyThis == theSOs.length) {copyThis = 0}
      };
// determine the target position;
   var theBounds = theLayer.bounds;
   var theHorOffset = Math.random() * theWidth - (theBounds[0] + ((theBounds[2] - theBounds[0])/2));
   var theVerOffset = Math.random() * theHeight - (theBounds[1] + ((theBounds[3] - theBounds[1])/2));
// calculate angle between the maller and the bigger one;
   var theAngle = theRotate1 + (Math.random() * (theRotate2 - theRotate1));
// calculate scale factors between the smaller and the bigger one;
   var theScale =  Math.random() * ((theScale2 - theScale1)) + theScale1;
// apply;
   try {
// attempt random flips;
      if (theFlip == true) {
         switch (Math.floor(Math.random()*2)) {
            case 0:
            var theHorScale = theScale;
            break;
            case 1:
            var theHorScale = theScale * (-1);
            break;
            }
         };
      duplicateMoveAndScale (myDocument, theSOs[copyThis][1], theAngle, theHorOffset, theVerOffset, theScale, theScale)
      }
   catch (e) {}
   };
// hide the original layers;
for (var o = 0; o < theLayers.length; o++) {theSOs[o][0].visible = false};
// reset;
app.preferences.rulerUnits = originalUnits;
myDocument.resizeImage(undefined, undefined, originalResolution, ResampleMethod.NONE);
app.togglePalettes();
var time2 = Number(timeString());
alert(((time2-time1)/1000)+" seconds\nstart "+time1+"\nend "+time2);
};
};
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
// by mike hale, via paul riggott;
// http://forums.adobe.com/message/1944754#1944754
function getLayerId(theLayer){
app.activeDocument.activeLayer = theLayer;
//Assumes activeDocument and activeLayer   
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    d = executeActionGet(ref);
return d.getInteger(charIDToTypeID('LyrI'));
};
////// function to smartify if not //////
function smartify (theLayer) {
app.activeDocument.activeLayer = theLayer;
// make layers smart objects if they are not already;
   if (theLayer.kind != LayerKind.SMARTOBJECT) {
      app.activeDocument.activeLayer = theLayer;
      var id557 = charIDToTypeID( "slct" );
      var desc108 = new ActionDescriptor();
      var id558 = charIDToTypeID( "null" );
      var ref77 = new ActionReference();
      var id559 = charIDToTypeID( "Mn  " );
      var id560 = charIDToTypeID( "MnIt" );
      var id561 = stringIDToTypeID( "newPlacedLayer" );
      ref77.putEnumerated( id559, id560, id561 );
      desc108.putReference( id558, ref77 );
      executeAction( id557, desc108, DialogModes.NO )
      }
   return app.activeDocument.activeLayer
   };
////// rotate and move //////
function duplicateMoveAndScale (myDocument, theIndex, thisAngle, horizontalOffset, verticalOffset, horScale, verScale) {
// duplicate by index;
// =======================================================
var idDplc = charIDToTypeID( "Dplc" );
    var desc3 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref1 = new ActionReference();
        ref1.putIdentifier( charIDToTypeID( "Lyr " ), theIndex );
    desc3.putReference( idnull, ref1 );
    var idVrsn = charIDToTypeID( "Vrsn" );
    desc3.putInteger( idVrsn, 5 );
executeAction( idDplc, desc3, DialogModes.NO );
// move topside;
//myDocument.activeLayer.move(myDocument.activeLayer.parent, ElementPlacement.PLACEATBEGINNING);
// do the transformations;
// =======================================================
var idTrnf = charIDToTypeID( "Trnf" );
    var desc3 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref2 = new ActionReference();
        var idLyr = charIDToTypeID( "Lyr " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref2.putEnumerated( idLyr, idOrdn, idTrgt );
    desc3.putReference( idnull, ref2 );
    var idFTcs = charIDToTypeID( "FTcs" );
    var idQCSt = charIDToTypeID( "QCSt" );
    var idQcsa = charIDToTypeID( "Qcsa" );
    desc3.putEnumerated( idFTcs, idQCSt, idQcsa );
    var idOfst = charIDToTypeID( "Ofst" );
        var desc4 = new ActionDescriptor();
        var idHrzn = charIDToTypeID( "Hrzn" );
        var idPxl = charIDToTypeID( "#Pxl" );
        desc4.putUnitDouble( idHrzn, idPxl, horizontalOffset );
        var idVrtc = charIDToTypeID( "Vrtc" );
        var idPxl = charIDToTypeID( "#Pxl" );
        desc4.putUnitDouble( idVrtc, idPxl, verticalOffset );
    var idOfst = charIDToTypeID( "Ofst" );
    desc3.putObject( idOfst, idOfst, desc4 );
    var idWdth = charIDToTypeID( "Wdth" );
    var idPrc = charIDToTypeID( "#Prc" );
    desc3.putUnitDouble( idWdth, idPrc, horScale );
    var idHght = charIDToTypeID( "Hght" );
    var idPrc = charIDToTypeID( "#Prc" );
    desc3.putUnitDouble( idHght, idPrc, verScale );
if (thisAngle != 0) {
    var idAngl = charIDToTypeID( "Angl" );
    var idAng = charIDToTypeID( "#Ang" );
    desc3.putUnitDouble( idAngl, idAng, thisAngle );
   };
executeAction( idTrnf, desc3, DialogModes.NO );
};
////// function to determine if open document is eligible for operations //////
function photoshopCheck () {
var checksOut = true;
if (app.documents.length == 0) {
   alert ("no document open");
   checksOut = false
   }
else {};
return checksOut
};
////// function to get the date //////
function timeString () {
   var now = new Date();
   return now.getTime()
   };
////// get the selected layers, thanks to paul riggott and mike hale //////
function GetSelectedLayers() {
var A=[];
    var desc11 = new ActionDescriptor();
        var ref9 = new ActionReference();
        ref9.putClass( stringIDToTypeID('layerSection') );
    desc11.putReference( charIDToTypeID('null'), ref9 );
        var ref10 = new ActionReference();
        ref10.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc11.putReference( charIDToTypeID('From'), ref10 );
    executeAction( charIDToTypeID('Mk  '), desc11, DialogModes.NO );
var gL = activeDocument.activeLayer.layers;
for(var i=0;i<gL.length;i++){
A.push(gL);
}
executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );
return A;
};
roberthpaige

Random Position, with Options to Scale and Resize

Post by roberthpaige »

Dear sir, you did it! Sorry for the late reply.

Can I donate something for your hard work?
pfaffenbichler

Random Position, with Options to Scale and Resize

Post by pfaffenbichler »

You are welcome.
I am just an occasional contributor on this site but I have myself received a lot of help from the regulars here, so if you really want to donate something I would consider this site a deserving recipient.
roberthpaige

Random Position, with Options to Scale and Resize

Post by roberthpaige »

pfaffenbichler wrote:You are welcome.
I am just an occasional contributor on this site but I have myself received a lot of help from the regulars here, so if you really want to donate something I would consider this site a deserving recipient.

Quick question, would it be possible to do this with selected objects, without the copies?
pfaffenbichler

Random Position, with Options to Scale and Resize

Post by pfaffenbichler »

You mean just reposition, scale and rotate the selected Layers randomly?
That would be possible.

Consecutive runs could pose a problem, though, in that I know no direct method of determining the scale and rotation of a Smart Object, so those may add up relative to the original elements.