0

so i would like to have a script that rotates a layer 64 time by 5.625 degrees but every time before it rotates, it resets the layer to its original state(as rotating from the previus loses quality) so have it rotate by x+5.625.

I would like to save each image separately.

8
  • Why would it be any different from rotating 64*5625? Or is it 5.625? Remenber in english locales comma is a thousands separator which makes it unclear
    – joojaa
    Commented Nov 6, 2020 at 7:15
  • i want it revert to its original state before rotating again to the next position. yes i mean 5.625
    – tolis97d
    Commented Nov 6, 2020 at 7:17
  • undo? Anyway its not clear in your question you want copies or not.
    – joojaa
    Commented Nov 6, 2020 at 7:18
  • If you use a Smart Object, you won't loose quality from each rotation.
    – Wolff
    Commented Nov 6, 2020 at 7:19
  • Use smart objects is another possibility
    – joojaa
    Commented Nov 6, 2020 at 7:20

2 Answers 2

1

Now that you have expanded your question to explain what you want, the question is entirely different. Before it was a XY problem please avoid that.

Do this:

  1. Make the image into a smart layer
  2. open timeline and create video timeline
    • Go to timeline hamburger menu -> panel options and set the time format to frames
    • Go to frame 64 (first frame is 0 but we will skip the last frame when expoting) then choose timeline hamburger menu -> move and trim -> trim end of playhead
  3. Go to frame 0
    • click on the arrow next to layer in timeline.
    • click on transform, this enables transform of video layer
  4. go to frame 31
    • trasform your layer 180 degrees (hit ctrl+t) then enter
  5. go to frame 64
    • trasform your layer 180 degrees agaibn (hit ctrl+t) then enter
  6. grab the timeline subsectioning tab and move it one frame back ignoring frame 64
  7. Save animation out as image sequence by choosing timeline hamburger menu -> Render video.
    • Chose Photoshop image sequence in the type dropdown (it has no name so it might read media encoder)
    • fill in filename, location, naming conventions and render

Done

1
  • ok i will try that. yes after each rotation i want to save it as png sorry wasnt clear
    – tolis97d
    Commented Nov 6, 2020 at 7:32
0

Things like this are super easy to do with the ScriptingListener plugin — takes literally a minute or two.

So I have an image with a layer (as a smart object) that I want to rotate:

enter image description here

I rotate the layer the way I want: exact numbers aren't important now. And then save it as a .png

enter image description here

ScriptingListener will generate a .log file on the desktop. There's some garbage but I know I need 2 things: a transform and a save. So I look for a block with some numbers and a block with a save path. Here are they:

// =======================================================
var idTrnf = charIDToTypeID( "Trnf" );
    var desc12 = new ActionDescriptor();
    var idFTcs = charIDToTypeID( "FTcs" );
    var idQCSt = charIDToTypeID( "QCSt" );
    var idQcsi = charIDToTypeID( "Qcsi" );
    desc12.putEnumerated( idFTcs, idQCSt, idQcsi );
    var idPstn = charIDToTypeID( "Pstn" );
        var desc13 = new ActionDescriptor();
        var idHrzn = charIDToTypeID( "Hrzn" );
        var idPxl = charIDToTypeID( "#Pxl" );
        desc13.putUnitDouble( idHrzn, idPxl, 251.985380 );
        var idVrtc = charIDToTypeID( "Vrtc" );
        var idPxl = charIDToTypeID( "#Pxl" );
        desc13.putUnitDouble( idVrtc, idPxl, 284.023392 );
    var idPnt = charIDToTypeID( "Pnt " );
    desc12.putObject( idPstn, idPnt, desc13 );
    var idOfst = charIDToTypeID( "Ofst" );
        var desc14 = new ActionDescriptor();
        var idHrzn = charIDToTypeID( "Hrzn" );
        var idPxl = charIDToTypeID( "#Pxl" );
        desc14.putUnitDouble( idHrzn, idPxl, 0.000000 );
        var idVrtc = charIDToTypeID( "Vrtc" );
        var idPxl = charIDToTypeID( "#Pxl" );
        desc14.putUnitDouble( idVrtc, idPxl, -0.000000 );
    var idOfst = charIDToTypeID( "Ofst" );
    desc12.putObject( idOfst, idOfst, desc14 );
    var idAngl = charIDToTypeID( "Angl" );
    var idAng = charIDToTypeID( "#Ang" );
    desc12.putUnitDouble( idAngl, idAng, 7.740591 );
executeAction( idTrnf, desc12, DialogModes.NO );

// =======================================================
var idsave = charIDToTypeID( "save" );
    var desc21 = new ActionDescriptor();
    var idAs = charIDToTypeID( "As  " );
        var desc22 = new ActionDescriptor();
        var idMthd = charIDToTypeID( "Mthd" );
        var idPNGMethod = stringIDToTypeID( "PNGMethod" );
        var idquick = stringIDToTypeID( "quick" );
        desc22.putEnumerated( idMthd, idPNGMethod, idquick );
        var idPGIT = charIDToTypeID( "PGIT" );
        var idPGIT = charIDToTypeID( "PGIT" );
        var idPGIN = charIDToTypeID( "PGIN" );
        desc22.putEnumerated( idPGIT, idPGIT, idPGIN );
        var idPNGf = charIDToTypeID( "PNGf" );
        var idPNGf = charIDToTypeID( "PNGf" );
        var idPGAd = charIDToTypeID( "PGAd" );
        desc22.putEnumerated( idPNGf, idPNGf, idPGAd );
        var idCmpr = charIDToTypeID( "Cmpr" );
        desc22.putInteger( idCmpr, 6 );
    var idPNGF = charIDToTypeID( "PNGF" );
    desc21.putObject( idAs, idPNGF, desc22 );
    var idIn = charIDToTypeID( "In  " );
    desc21.putPath( idIn, new File( "E:\\temp\\del\\test\\01.png" ) );
    var idDocI = charIDToTypeID( "DocI" );
    desc21.putInteger( idDocI, 821 );
    var idCpy = charIDToTypeID( "Cpy " );
    desc21.putBoolean( idCpy, true );
    var idsaveStage = stringIDToTypeID( "saveStage" );
    var idsaveStageType = stringIDToTypeID( "saveStageType" );
    var idsaveBegin = stringIDToTypeID( "saveBegin" );
    desc21.putEnumerated( idsaveStage, idsaveStageType, idsaveBegin );
executeAction( idsave, desc21, DialogModes.NO );

Now it's a matter of converting this to a function. Final script and result:

enter image description here

var i;
var copies = 64;
var angle = 360 / copies;

for (i = 0; i < copies; i++) {
    rotate(angle, i)
}

function rotate(angle, i)
{
  // =======================================================
  var idTrnf = charIDToTypeID("Trnf");
  var desc12 = new ActionDescriptor();
  var idFTcs = charIDToTypeID("FTcs");
  var idQCSt = charIDToTypeID("QCSt");
  var idQcsi = charIDToTypeID("Qcsi");
  desc12.putEnumerated(idFTcs, idQCSt, idQcsi);
  var idPstn = charIDToTypeID("Pstn");
  var desc13 = new ActionDescriptor();
  var idHrzn = charIDToTypeID("Hrzn");
  var idPxl = charIDToTypeID("#Pxl");
  desc13.putUnitDouble(idHrzn, idPxl, 251.985380);
  var idVrtc = charIDToTypeID("Vrtc");
  var idPxl = charIDToTypeID("#Pxl");
  desc13.putUnitDouble(idVrtc, idPxl, 284.023392);
  var idPnt = charIDToTypeID("Pnt ");
  desc12.putObject(idPstn, idPnt, desc13);
  var idOfst = charIDToTypeID("Ofst");
  var desc14 = new ActionDescriptor();
  var idHrzn = charIDToTypeID("Hrzn");
  var idPxl = charIDToTypeID("#Pxl");
  desc14.putUnitDouble(idHrzn, idPxl, 0.000000);
  var idVrtc = charIDToTypeID("Vrtc");
  var idPxl = charIDToTypeID("#Pxl");
  desc14.putUnitDouble(idVrtc, idPxl, -0.000000);
  var idOfst = charIDToTypeID("Ofst");
  desc12.putObject(idOfst, idOfst, desc14);
  var idAngl = charIDToTypeID("Angl");
  var idAng = charIDToTypeID("#Ang");
  desc12.putUnitDouble(idAngl, idAng, angle);
  executeAction(idTrnf, desc12, DialogModes.NO);

  // =======================================================
  var idsave = charIDToTypeID("save");
  var desc21 = new ActionDescriptor();
  var idAs = charIDToTypeID("As  ");
  var desc22 = new ActionDescriptor();
  var idMthd = charIDToTypeID("Mthd");
  var idPNGMethod = stringIDToTypeID("PNGMethod");
  var idquick = stringIDToTypeID("quick");
  desc22.putEnumerated(idMthd, idPNGMethod, idquick);
  var idPGIT = charIDToTypeID("PGIT");
  var idPGIT = charIDToTypeID("PGIT");
  var idPGIN = charIDToTypeID("PGIN");
  desc22.putEnumerated(idPGIT, idPGIT, idPGIN);
  var idPNGf = charIDToTypeID("PNGf");
  var idPNGf = charIDToTypeID("PNGf");
  var idPGAd = charIDToTypeID("PGAd");
  desc22.putEnumerated(idPNGf, idPNGf, idPGAd);
  var idCmpr = charIDToTypeID("Cmpr");
  desc22.putInteger(idCmpr, 6);
  var idPNGF = charIDToTypeID("PNGF");
  desc21.putObject(idAs, idPNGF, desc22);
  var idIn = charIDToTypeID("In  ");
  desc21.putPath(idIn, new File("E:\\temp\\del\\test\\F22_"+pad(i,4)+".png"));
  var idDocI = charIDToTypeID("DocI");
  desc21.putInteger(idDocI, 821);
  var idCpy = charIDToTypeID("Cpy ");
  desc21.putBoolean(idCpy, true);
  var idsaveStage = stringIDToTypeID("saveStage");
  var idsaveStageType = stringIDToTypeID("saveStageType");
  var idsaveBegin = stringIDToTypeID("saveBegin");
  desc21.putEnumerated(idsaveStage, idsaveStageType, idsaveBegin);
  executeAction(idsave, desc21, DialogModes.NO);

}

function pad(n, width, z)
{
  z = z || '0';
  n = n + '';
  return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
6
  • Yes but its still an animation so better animate, easier to edit. But also if one bothers to read the api docs youll find it can be done with much less code.
    – joojaa
    Commented Nov 6, 2020 at 13:02
  • @joojaa I agree, but why not to suggest a different approach? That also could be a way for resolving more complex tasks later on for someone. Commented Nov 6, 2020 at 14:34
  • Ues, but not really easy to extend.
    – joojaa
    Commented Nov 6, 2020 at 14:40
  • @joojaa Why? I think it's easy extendable when you know the principle — finding the parts you need in the AM log and some very basic JS. Commented Nov 6, 2020 at 15:22
  • Part of the reason to write code is to make your process understandable. This aint it. But yeah its easy do though. You could have recorded a action and looped that would have been even easier.
    – joojaa
    Commented Nov 6, 2020 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.