What's new
Photoshop Gurus Forum

Welcome to Photoshop Gurus forum. Register a free account today to become a member! It's completely free. Once signed in, you'll enjoy an ad-free experience and be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Batch Automation Batching TIFFs>JPG/PNG w/ automatic resize based on filesize


jimmybreeze

New Member
Messages
4
Likes
0
Hi there,

I'm pretty new to all this stuff but I've been doing a LOT of processing of images of late. I'm sure what I want to do can be done with scripts or automation though.

My scenario is this:

I have a folder with a lot of subfolders, many with a bunch of TIFFs inside. Some of these have transparency in them while some don't. These files vary massively in size.

I need all the files to be turned into JPGs, or if they contain transparency, PNGs. I require the files to be 200kb or less and don't really mind how large they are as long as they aren't scaled up.

I spotted this bit of script and was wondering if that might be at least a little useful as a start but I'd much rather learn a little more about how scripting might be able to assist me in this situation.


var SizeOfFile = prompt("Please Enter Size In Megabytes",17)
if (SizeOfFile > 0) resizeToMB( SizeOfFile );

function resizeToMB( size_in_MB ) {
var current_units = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var width_pixels = activeDocument.width;
var height_pixels = activeDocument.height;
var channel_count = activeDocument.channels.length;
var final_size = ( 1024 * 1024 * size_in_MB ) / channel_count;
var image_bytes = width_pixels * height_pixels;
var image_scale = Math.sqrt( final_size/ image_bytes );
var final_width = width_pixels * image_scale;
var final_height = height_pixels * image_scale;
var final_dpi = activeDocument.resolution;
if ( image_scale > 1 ) {
activeDocument.resizeImage( final_width, final_height, final_dpi, ResampleMethod.BICUBICSMOOTHER );
} else {
activeDocument.resizeImage( final_width, final_height, final_dpi, ResampleMethod.BICUBICSHARPER );
}
preferences.rulerUnits = current_units;
}

I don't know if you guys could help me but anything you could would be massively appreciated and would totally help me out of this nightmare. I've got around 500GB of data to get through.

Thanks in advance,

Dan
 
Hi Dan, a couple of things. The bit of code you have posted is the size in memory not the size on the hard disk so no that is not useful.
The 200kb limit is also a big problem, PNG files can be quite large and there must be a compromise on the quality of saving jpgs, saving as save for web will reduce the size.

There is no way of checking the size a file will be, you can only save it, check the size delete it and save with a lower quality. This is very inefficiant and takes a long time.

If you are happy about about this I will put something together.
Are the new files to be saved along side the original tif files in the original folders?
 
This code should be close...

Code:
#target Photoshop
app.bringToFront();
function main(){
var folders =[];
var topLevel = Folder.selectDialog("Please select top level folder"); 
folders = FindAllFolders(topLevel, folders);
folders.unshift(topLevel);
for(var f in folders){
    var fileList = folders[f].getFiles(/\.(tif)$/i);
    for(var z in fileList){
        open(fileList[z]);
        try{
        activeDocument.mergeVisibleLayers();
        }catch(e){}
        var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');
        if(loadTransparency()){
            var saveFile = File(folders[f] + "/" + Name + ".png");
                SavePNG(saveFile);
                app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
            }else{
                var saveFile = File(folders[f] + "/" + Name + ".jpg");
                SaveForWeb(saveFile,80);
                app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
        }
    }
alert("Batch complete");
}
main();
function FindAllFolders( srcFolderStr, destArray) {
 var fileFolderArray = Folder( srcFolderStr ).getFiles();
 for ( var i = 0; i < fileFolderArray.length; i++ ) {
  var fileFoldObj = fileFolderArray[i];
  if ( fileFoldObj instanceof File ) {   
  } else {
         destArray.push( Folder(fileFoldObj) );
  FindAllFolders( fileFoldObj.toString(), destArray );
  }
 }
 return destArray;
}
function loadTransparency(){
var doc = activeDocument;
if(doc.activeLayer.isBackgroundLayer) return false;
   var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) );
    desc.putReference( charIDToTypeID( "null" ), ref );
        var ref1 = new ActionReference();
        ref1.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Trsp" ) );
    desc.putReference( charIDToTypeID( "T   " ), ref1 );
   executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
var w = doc.width.as('px');
var h = doc.height.as('px');
var transChannel = doc.channels.add();
doc.selection.store( transChannel );
if( transChannel.histogram[255] != ( h * w ) ){
    transChannel.remove();
   return true;
}else{
    transChannel.remove();
   return false;
    }
};
function SavePNG(saveFile){
    pngSaveOptions = new PNGSaveOptions(); 
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE); 
}
function SaveForWeb(saveFile,jpegQuality) {
var sfwOptions = new ExportOptionsSaveForWeb(); 
   sfwOptions.format = SaveDocumentType.JPEG; 
   sfwOptions.includeProfile = false; 
   sfwOptions.interlaced = 0; 
   sfwOptions.optimized = true; 
   sfwOptions.quality = jpegQuality;
activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
}
 
Hey there, thanks ever so much for that,

A friend of mine adapted the script to my needs a little and came up with the following:

#target Photoshop

String.prototype.endsWith = function(str){
return (this.match(str+"$")==str)
}

String.prototype.startsWith = function (str){
return this.indexOf(str) == 0;
};


var desiredFileSize = 200000;

app.bringToFront();
app.displayDialogs = DialogModes.NO;

main();

//app.displayDialogs = DialogModes.YES;

function main(){
var topLevelFolder = Folder.selectDialog("Please select top level folder.");
if (topLevelFolder == null) return;

var FileList =[];
getFileList(topLevelFolder);

for(var f in FileList){

app.open(FileList[f]);

activeDocument.changeMode(ChangeMode.RGB);

try{
activeDocument.mergeVisibleLayers();
}catch(e){}
var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');

if(hasTransparency(FileList[f])){
var saveFile = File(FileList[f].path + "/" + Name + ".png");
SavePNG(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}else{
var saveFile = File(FileList[f].path + "/" + Name + ".jpg");
SaveForWeb(saveFile,80);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
}

function getFileList(folder) {
var fileList = folder.getFiles();

for (var i = 0; i < fileList.length; i++) {
var file = fileList;
if (file instanceof Folder) {
getFileList(file);
}
else{
if((file.name.endsWith("tiff") || file.name.endsWith("tif") || file.name.endsWith("psd"))
&& !file.name.startsWith("._") )
FileList.push(file);
}
}
}

alert(FileList.length + " files have been modified.");
}



function hasTransparency(file){
if(file.name.endsWith("tiff") || file.name.endsWith("tif")){
var doc = activeDocument;
if(doc.activeLayer.isBackgroundLayer) return false;
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) );
desc.putReference( charIDToTypeID( "null" ), ref );
var ref1 = new ActionReference();
ref1.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Trsp" ) );
desc.putReference( charIDToTypeID( "T " ), ref1 );
executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
var w = doc.width.as('px');
var h = doc.height.as('px');
var transChannel = doc.channels.add();
doc.selection.store( transChannel );
if( transChannel.histogram[255] != ( h * w ) ){
transChannel.remove();
return true;
}else{
transChannel.remove();
return false;
}
} else{
var sample = app.activeDocument.colorSamplers.add( [ new UnitValue( 1.5, 'px' ), new UnitValue( 1.5, 'px' ) ] );
try{
sample.color.rgb.hexValue;
sample.remove();

return false;
}catch(e){
return true;
}
}
};

function SavePNG(saveFile){
pngSaveOptions = new PNGSaveOptions();
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);

var actualFilesize = saveFile.length;
var ratio = desiredFileSize/actualFilesize;

if(ratio < 1){
var imageScale = Math.sqrt(ratio);
activeDocument.resizeImage( activeDocument.width*imageScale, activeDocument.height*imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER );
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
}
}

function SaveForWeb(saveFile,jpegQuality) {
var sfwOptions = new ExportOptionsSaveForWeb();
sfwOptions.format = SaveDocumentType.JPEG;
sfwOptions.includeProfile = false;
sfwOptions.interlaced = 0;
sfwOptions.optimized = true;
sfwOptions.quality = jpegQuality;
activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);

var actualFilesize = saveFile.length;
var ratio = desiredFileSize/actualFilesize;

if(ratio < 1){
var imageScale = Math.sqrt(ratio);
activeDocument.resizeImage( activeDocument.width*imageScale, activeDocument.height*imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER );
activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
}
}

Unfortunately it creates 1x1 pixels randomly out of files that I can't find any common factor of (other than the fact they're PSD/TIF and have no transparency).

It's very consistent with which ones are turned into these annoying 1x1 pixels. Doesn't sound like the end of the world but I've now gotta go through various subfolders, find them and convert them manually, which means this script isn't really saving much time :/

When my friend tried diagnosing this he found Photoshop said something along the lines of File does not exist.

I've attached an image which this happens to.

Thanks again :)
 

Attachments

There were a couple of problems with that code, it was not checking what the ruler units were set at so any resize that would be done would be using whatever the ruler units were set at. So if they were set for anything other than pixels the resize would be screwed.

The code that was added for using a colorSampler with a tif should have been seperate as nothing was getting tested except a tif.

The example psd now saves as a png
Hope this helps?

Code:
#target Photoshop
 
String.prototype.endsWith = function(str){
 return (this.match(str+"$")==str)
 }
 
String.prototype.startsWith = function (str){
 return this.indexOf(str) == 0;
 };
 
var desiredFileSize = 200000;
 
app.bringToFront();
 app.displayDialogs = DialogModes.NO;
 
main();
 
//app.displayDialogs = DialogModes.YES;
 
function main(){
var topLevelFolder = Folder.selectDialog("Please select top level folder."); 
if (topLevelFolder == null) return; 
var FileList =[]; 
getFileList(topLevelFolder); 
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
for(var f in FileList){ 
app.open(FileList[f]);
activeDocument.changeMode(ChangeMode.RGB);
 try{
 activeDocument.mergeVisibleLayers();
 }catch(e){}
 var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');
 if(hasTransparency(FileList[f])){
 var saveFile = File(FileList[f].path + "/" + Name + ".png");
 SavePNG(saveFile);
 app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
 }else{
 var saveFile = File(FileList[f].path + "/" + Name + ".jpg");
 SaveForWeb(saveFile,80);
 app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
 } 
app.preferences.rulerUnits = startRulerUnits;
} 
function getFileList(folder) { 
var fileList = folder.getFiles();
 for (var i = 0; i < fileList.length; i++) { 
var file = fileList[i]; 
if (file instanceof Folder) { 
getFileList(file); 
} 
else{
 if((file.name.endsWith("tiff") || file.name.endsWith("tif") || file.name.endsWith("psd")) && !file.name.startsWith("._") )
 FileList.push(file);
 }
 } 
}
 alert(FileList.length + " files have been modified."); 
} 
function hasTransparency(file){
 if(file.name.endsWith("tiff") || file.name.endsWith("tif")){
 var sample = app.activeDocument.colorSamplers.add( [ new UnitValue( 1.5, 'px' ), new UnitValue( 1.5, 'px' ) ] );
 try{
 sample.color.rgb.hexValue;
 sample.remove();
 return false;
 }catch(e){
      sample.remove();
 return true;
 }
}
 var doc = activeDocument;
 if(doc.activeLayer.isBackgroundLayer) return false;
 var desc = new ActionDescriptor();
 var ref = new ActionReference();
 ref.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) );
 desc.putReference( charIDToTypeID( "null" ), ref );
 var ref1 = new ActionReference();
 ref1.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Trsp" ) );
 desc.putReference( charIDToTypeID( "T   " ), ref1 );
 executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
 var w = doc.width.as('px');
 var h = doc.height.as('px');
 var transChannel = doc.channels.add();
 doc.selection.store( transChannel );
 if( transChannel.histogram[255] != ( h * w ) ){
 transChannel.remove();
 return true;
 }else{
 transChannel.remove();
 return false;
 }
 };
 
function SavePNG(saveFile){
pngSaveOptions = new PNGSaveOptions(); 
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE); 
var actualFilesize = saveFile.length;
 var ratio = desiredFileSize/actualFilesize;
if(ratio < 1){
 var imageScale = Math.sqrt(ratio);
 activeDocument.resizeImage( activeDocument.width*imageScale, activeDocument.height*imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER );
 activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE); 
}
 }
 
function SaveForWeb(saveFile,jpegQuality) {
 var sfwOptions = new ExportOptionsSaveForWeb(); 
sfwOptions.format = SaveDocumentType.JPEG; 
sfwOptions.includeProfile = false; 
sfwOptions.interlaced = 0; 
sfwOptions.optimized = true; 
sfwOptions.quality = jpegQuality;
 activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
 var actualFilesize = saveFile.length;
 var ratio = desiredFileSize/actualFilesize;
 if(ratio < 1){
 var imageScale = Math.sqrt(ratio);
 activeDocument.resizeImage( activeDocument.width*imageScale, activeDocument.height*imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER );
 activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
 }
 }
 
Thanks a lot!!!!

I must say I forgot to say in my original post that I was indeed testing for PSDs and TIFs, does this make a difference to what you've just posted.
 
The original code only looked for TIFs but this last code works with TIFs or PSDs

I don't understand why the code is there to test a tif with a colorsampler though, as it's only testing one pixel.
 
That worked with the file I uploaded but not with some of the others I've been using to test with. I had exactly the same 1x1 pixel result.

Interestingly, when I've tried to attach any of the files to this post I've been told it's invalid :/

Hmmm.
 

Back
Top