• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Making Chop-o-Matic more adaptive ?

Community Beginner ,
Feb 21, 2020 Feb 21, 2020

Copy link to clipboard

Copied

Hello dear Photoshop fellows,

I am working on webcomics scroll documents (960 x 95000 + px), and the most tedious part of the job consists in slicing the scroll into 1280 pixels height JPGs files... For the moment, the team laboriously worked with a Photoshop Action, but it needed to be relaunched and manually numbered for every file.
Typically a task for a script, you would tell me !

I did some Python programming by the past, but none on Javascript, neither with Photoshop SDK.

After a first theorical design for the script I needed, I stumbled here upon the Chop-O-Matic script (this page ), which makes 90% of the job, which is great, but i need to tweak it, based on my needs. I'll leave my algorithm sketch at bottom of this message.

 

What I need to suppress from chop-o-matic :

- dialog window ;

- no need to slice across.

 

What I need to modify in chop-o-matic :

- instead of a fixed amount of slices, the new script should make the maths itself, like :

 

numberOfSlices = math.ceil(currentDocumentHeight / 1280)

 

The total height of main scroll varies from episode to episode, but every slice of it would always be 1280 px tall.

 

- the current version of chop-o-matic outputed 1279 px tall files, instead of 1280 px. ...
I guess it is due to integer approximation of current version of chop-o-matic.

 

- I need to change JPEG output so that it is quality 10, progressive scan with 3 passes ;

 

- The numbering of created files just need to be "000-999.jpg" template.

 

And that's it. Apart from specified above, the existing script does the job.
Kudos to Paul_Riggot, by the way. 🙂

 

This is my initial script design, before discovering Chop-o-Matic :

 

Focus on open document ;
Duplicate and save a PSD copy at the same level ;
Flatten current document (no dialog) ;
Focus on duplicated document ;

var sliceHeight = 1280
var sliceSerial = 000
var nameSerial = 000

get current document's height (in pixel) ;
//pre-slicing calculation...
var sliceSerial = Math.ceil(doc height / SliceHeight)

//start of loop
	if (sliceSerial > 1) {
	duplicate current document ;
	focus on newly created document ;
	Set canvas size to 1280 px height, with relative anchor top center ;
	Save current document to JPEG, quality 10, progressive scan, 3 passes, located at ../Sliced_JPGs/, named "nameSerial.jpg" , (no dialog displayed) ;
	
	var sliceSerial --
	var nameSerial ++
	
	close current document, NOSAVE ;
	}
	
	else {
	duplicate current document ;
	focus on newly created document ;
	Save current document to JPEG, quality 10, progressive scan, 3 passes, located at ../Sliced_JPGs/, named "nameSerial.jpg" , (no dialog displayed) ;
	close current document, NOSAVE ;
	}
//end of loop
// variables reinitialization	
var sliceSerial = 000
var nameSerial = 000

Close current document //the long scroll

 

Thanks for your attention !

TOPICS
Actions and scripting

Views

373

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Feb 23, 2020 Feb 23, 2020

Here's the script that will place the slices in a subfolder.

#target photoshop

var count = 1000
var docOrig = activeDocument;
var docPath = new Folder(docOrig.path + '/jpgs/');
if(!docPath.exists){docPath.create()};
dupDoc ();
var doc = activeDocument;
docOrig.close(SaveOptions.DONOTSAVECHANGES);

var docHeight = doc.height.value;
var sliceNum = Math.ceil(docHeight/1280);

for(var i=0;i<sliceNum;i++){
    if(i<sliceNum-1){
        cropDoc (i*1280, i*1280+1280);
        }
    else{
        cropD
...

Votes

Translate

Translate
Adobe
Community Expert ,
Feb 21, 2020 Feb 21, 2020

Copy link to clipboard

Copied

Try this. You have an open file, which has to have been saved. The script will make a flattened duplicate file, and close the original. It will then make slices of the image in 1280 increments, other than the last, which will be the remainder. It will save in the same folder as the original with file names starting at 000. Then it will close the duplicate file, and not save it.

#target photoshop

var count = 1000
var docOrig = activeDocument;
var docPath = docOrig.path
dupDoc ();
var doc = activeDocument;
docOrig.close(SaveOptions.DONOTSAVECHANGES);

var docHeight = doc.height.value;
var sliceNum = Math.ceil(docHeight/1280);

for(var i=0;i<sliceNum;i++){
    if(i<sliceNum-1){
        cropDoc (i*1280, i*1280+1280);
        }
    else{
        cropDoc (i*1280, doc.height.value);
        }
    
    saveJpg (docPath + '/'+ count.toString().substr (1, 3))
    count++
    
    doc.activeHistoryState = doc.historyStates[0];
    }

doc.close(SaveOptions.DONOTSAVECHANGES)

function dupDoc(){
        var idDplc = charIDToTypeID( "Dplc" );
        var desc5 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idDcmn = charIDToTypeID( "Dcmn" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrst = charIDToTypeID( "Frst" );
            ref1.putEnumerated( idDcmn, idOrdn, idFrst );
        desc5.putReference( idnull, ref1 );
        var idMrgd = charIDToTypeID( "Mrgd" );
        desc5.putBoolean( idMrgd, true );
    executeAction( idDplc, desc5, DialogModes.NO );
    };

function cropDoc(topC, bottomC){
    var idCrop = charIDToTypeID( "Crop" );
        var desc30 = new ActionDescriptor();
        var idT = charIDToTypeID( "T   " );
            var desc31 = new ActionDescriptor();
            var idTop = charIDToTypeID( "Top " );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idTop, idPxl, topC );
            var idLeft = charIDToTypeID( "Left" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idLeft, idPxl, 0.000000 );
            var idBtom = charIDToTypeID( "Btom" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idBtom, idPxl, bottomC );
            var idRght = charIDToTypeID( "Rght" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idRght, idPxl, doc.width.value );
        var idRctn = charIDToTypeID( "Rctn" );
        desc30.putObject( idT, idRctn, desc31 );
        var idAngl = charIDToTypeID( "Angl" );
        var idAng = charIDToTypeID( "#Ang" );
        desc30.putUnitDouble( idAngl, idAng, 0.000000 );
        var idDlt = charIDToTypeID( "Dlt " );
        desc30.putBoolean( idDlt, false );
        var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );
        var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );
        var idpureAspectRatio = stringIDToTypeID( "pureAspectRatio" );
        desc30.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idpureAspectRatio );
        var idCnsP = charIDToTypeID( "CnsP" );
        desc30.putBoolean( idCnsP, false );
    executeAction( idCrop, desc30, DialogModes.NO );    
    }

function saveJpg(fName){
    var idsave = charIDToTypeID( "save" );
        var desc40 = new ActionDescriptor();
        var idAs = charIDToTypeID( "As  " );
            var desc41 = new ActionDescriptor();
            var idEQlt = charIDToTypeID( "EQlt" );
            desc41.putInteger( idEQlt, 10 );
            var idScns = charIDToTypeID( "Scns" );
            desc41.putInteger( idScns, 3 );
            var idMttC = charIDToTypeID( "MttC" );
            var idMttC = charIDToTypeID( "MttC" );
            var idNone = charIDToTypeID( "None" );
            desc41.putEnumerated( idMttC, idMttC, idNone );
        var idJPEG = charIDToTypeID( "JPEG" );
        desc40.putObject( idAs, idJPEG, desc41 );
        var idIn = charIDToTypeID( "In  " );
        desc40.putPath( idIn, new File( fName +'.jpg' ) );
        var idDocI = charIDToTypeID( "DocI" );
        desc40.putInteger( idDocI, 256 );
        var idCpy = charIDToTypeID( "Cpy " );
        desc40.putBoolean( idCpy, true );
        var idsaveStage = stringIDToTypeID( "saveStage" );
        var idsaveStageType = stringIDToTypeID( "saveStageType" );
        var idsaveBegin = stringIDToTypeID( "saveBegin" );
        desc40.putEnumerated( idsaveStage, idsaveStageType, idsaveBegin );
    executeAction( idsave, desc40, DialogModes.NO );    
    }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 23, 2020 Feb 23, 2020

Copy link to clipboard

Copied

Chuck, you are such a prodigious person ! 🙂
The script you provided is exactly what I needed !

 

Me and other teammates definitely owe you something for saving us time for creative tasks.

 

I've checked the script output files with previous handmade files : it meets the desired dimensions, and remain pixel-perfect with original scroll image file.

 

You've done an amazing work, but with my knowledge, I feel lost when it comes to make minor changes in script behaviour...

 

Maybe should I mention one feature I think would make everyday life easier, especially in stressing times ?

 

It would be to create a subfolder alongside the current PSD/PSB file, where all the generated JPGs would be saved to.


This behaviour is present in original Chop-o-Matic script, and I really appreciated it, for not 'polluting' current file organisation. Also when we it is time to drop sliced images to the FTP repository, it's faster to drop a single folder, with 100 % JPGs files in it, rather than having to manually exclude an unwanted big PSD/PSB file.

 

And eventually, the script would be PER-FECT ! 🙂
I wish you all the best for your benevolent support.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2020 Feb 23, 2020

Copy link to clipboard

Copied

Here's the script that will place the slices in a subfolder.

#target photoshop

var count = 1000
var docOrig = activeDocument;
var docPath = new Folder(docOrig.path + '/jpgs/');
if(!docPath.exists){docPath.create()};
dupDoc ();
var doc = activeDocument;
docOrig.close(SaveOptions.DONOTSAVECHANGES);

var docHeight = doc.height.value;
var sliceNum = Math.ceil(docHeight/1280);

for(var i=0;i<sliceNum;i++){
    if(i<sliceNum-1){
        cropDoc (i*1280, i*1280+1280);
        }
    else{
        cropDoc (i*1280, doc.height.value);
        }
    
    saveJpg (docPath + '/'+ count.toString().substr (1, 3))
    count++
    
    doc.activeHistoryState = doc.historyStates[0];
    }

doc.close(SaveOptions.DONOTSAVECHANGES)

function dupDoc(){
        var idDplc = charIDToTypeID( "Dplc" );
        var desc5 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idDcmn = charIDToTypeID( "Dcmn" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrst = charIDToTypeID( "Frst" );
            ref1.putEnumerated( idDcmn, idOrdn, idFrst );
        desc5.putReference( idnull, ref1 );
        var idMrgd = charIDToTypeID( "Mrgd" );
        desc5.putBoolean( idMrgd, true );
    executeAction( idDplc, desc5, DialogModes.NO );
    };

function cropDoc(topC, bottomC){
    var idCrop = charIDToTypeID( "Crop" );
        var desc30 = new ActionDescriptor();
        var idT = charIDToTypeID( "T   " );
            var desc31 = new ActionDescriptor();
            var idTop = charIDToTypeID( "Top " );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idTop, idPxl, topC );
            var idLeft = charIDToTypeID( "Left" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idLeft, idPxl, 0.000000 );
            var idBtom = charIDToTypeID( "Btom" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idBtom, idPxl, bottomC );
            var idRght = charIDToTypeID( "Rght" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc31.putUnitDouble( idRght, idPxl, doc.width.value );
        var idRctn = charIDToTypeID( "Rctn" );
        desc30.putObject( idT, idRctn, desc31 );
        var idAngl = charIDToTypeID( "Angl" );
        var idAng = charIDToTypeID( "#Ang" );
        desc30.putUnitDouble( idAngl, idAng, 0.000000 );
        var idDlt = charIDToTypeID( "Dlt " );
        desc30.putBoolean( idDlt, false );
        var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );
        var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );
        var idpureAspectRatio = stringIDToTypeID( "pureAspectRatio" );
        desc30.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idpureAspectRatio );
        var idCnsP = charIDToTypeID( "CnsP" );
        desc30.putBoolean( idCnsP, false );
    executeAction( idCrop, desc30, DialogModes.NO );    
    }

function saveJpg(fName){
    var idsave = charIDToTypeID( "save" );
        var desc40 = new ActionDescriptor();
        var idAs = charIDToTypeID( "As  " );
            var desc41 = new ActionDescriptor();
            var idEQlt = charIDToTypeID( "EQlt" );
            desc41.putInteger( idEQlt, 10 );
            var idScns = charIDToTypeID( "Scns" );
            desc41.putInteger( idScns, 3 );
            var idMttC = charIDToTypeID( "MttC" );
            var idMttC = charIDToTypeID( "MttC" );
            var idNone = charIDToTypeID( "None" );
            desc41.putEnumerated( idMttC, idMttC, idNone );
        var idJPEG = charIDToTypeID( "JPEG" );
        desc40.putObject( idAs, idJPEG, desc41 );
        var idIn = charIDToTypeID( "In  " );
        desc40.putPath( idIn, new File( fName +'.jpg' ) );
        var idDocI = charIDToTypeID( "DocI" );
        desc40.putInteger( idDocI, 256 );
        var idCpy = charIDToTypeID( "Cpy " );
        desc40.putBoolean( idCpy, true );
        var idsaveStage = stringIDToTypeID( "saveStage" );
        var idsaveStageType = stringIDToTypeID( "saveStageType" );
        var idsaveBegin = stringIDToTypeID( "saveBegin" );
        desc40.putEnumerated( idsaveStage, idsaveStageType, idsaveBegin );
    executeAction( idsave, desc40, DialogModes.NO );    
    }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 23, 2020 Feb 23, 2020

Copy link to clipboard

Copied

LATEST

Woah, Chuck, you truly are a gold person !

An immense THANK to you, dear sir !

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines