Mobile app version of vmapp.org
Login or Join
Murphy569

: Advice on batch exporting sections of an image I have a large PSB file (33600x19200px) and I need to write a script to export sections of this image as a series of images. What would the

@Murphy569

Posted in: #AdobePhotoshop #Automation #PhotoshopScripting

I have a large PSB file (33600x19200px) and I need to write a script to export sections of this image as a series of images. What would the best approach be ?

Initially I thought about scripting slices and exporting, but Save for Web is diabled for this resolution.

Another option I thought was this:


loop through each section I need to export
make a selection
copy pixels
create a new document
paste pixels
save for the web with the format and name I need
close the document without saving
goto 1


Is this the best approach ? What are your suggestions ?

Update:

Here's my script with the steps above:
#target photoshop

var doc = app.activeDocument;
var sel = doc.selection;//main document selection
var rows = 70;
var cols = 40;
var cell = 240;//size of a cell/display image/region of interest
var space=240; //space in between cells
var dname = doc.name.substr(0,doc.name.length-4);
var dir = doc.path.toString()+"/";
var dpi72 = 182.88036576073152146304292608585;
var options = new ExportOptionsSaveForWeb();
options.format = SaveDocumentType.JPEG;
options.quality = 75;

//*
for(var y = 0; y < cols; y++){
for(var x = 0 ; x < rows; x++){
var xpos = (x * (cell+space))+((1-y%2) * space);//+ di-grid offset
var ypos = (y * (cell+space));

try{

sel.select([[xpos,ypos],[xpos+cell,ypos],[xpos+cell,ypos+cell],[xpos,ypos+cell]],SelectionType.REPLACE,0,false);
sel.copy(true);

var nname = dname + "_"+((x+1)) + "_" + ((y+1));
//$.writeln("["+x+"]["+y+"]" +nname +"n"+sel.bounds);
//*
var small = app.documents.add(cell,cell,dpi72,dname,NewDocumentMode.RGB,DocumentFill.WHITE);

app.activeDocument = small;

small.paste();
small.exportDocument (new File(dir + "/" + nname + ".jpg"), ExportType.SAVEFORWEB, options);
small.close(SaveOptions.DONOTSAVECHANGES);

app.activeDocument = doc;
//*/
}catch(err){
x = rows;
y = cols;
alert(err);
}
}
}


The script works, but it's a bit slow. Is my approach ok or is there a faster way to do this ?

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Murphy569

1 Comments

Sorted by latest first Latest Oldest Best

 

@Carla748

This should be a lot faster. Instead of copy and pasting into a new file hundreds of times, it does this:


Makes the Background into a Layer.
Reduces the Canvas size down to the cell size.
Slides the Layer around 'under' the Canvas to the correct location.
Does a "Save For Web" essentially the same as your script.
Go to 3 and repeat, then stop when it runs out of pixels to nibble on.


It calculates the number of Cells per row, as well as the number of rows. No pre-configuration is needed!

There are some variables you can set at the beginning of the file should you ever need to.


NOTE: The script assumes that you start with a flattened file, and MAKE SURE YOU HAVE A BACKUP COPY of your artwork just in case anything goes wrong.


On my machine at work (absolutely nothing fancy or powerful, just a beater PC) it created the 350 tiles of your sample file in about 6 minutes. You can help the speed by hiding the Tools and Pallets (by pressing Tab) before running the script. Also, minimizing Photoshop while the script runs seems to help a bit too.



// Alter these as needed
var cellWidth = 240; // The width, in px, of your image cell
var cellHeight = 240; // The height, in px, of your image cell
var xOffset = 240; // The space, in px, between each cell in a row
var yOffset = 240; // The space, in px, between each row. Set to 0 for traditional checker board effect
var options = new ExportOptionsSaveForWeb();
options.format = SaveDocumentType.JPEG;
options.quality = 75;

// Don't change these unless you know why you should! :)
var doc = app.activeDocument;
var dname = doc.name.substr(0,doc.name.length-4);
var dir = doc.path.toString()+"/";
var rowShift = true;
var imageWidth = activeDocument.width.as('px');
var imageHeight = activeDocument.height.as('px');

// Store the current rulerUnits for later. We're going to change
// it to pixels for now, and we want to change it back later.
var myRulerUnits = app.preferences.rulerUnits;

// Set rulerUnits to pixels
app.preferences.rulerUnits = Units.PIXELS;

// Find the "Background"
var layerRef = doc.artLayers.getByName("Background");

// Set our "Background" to be a Layer
layerRef.isBackgroundLayer = false;

// Reduce the Canvas size to our cell size
doc.resizeCanvas(cellWidth, cellHeight, AnchorPosition.TOPLEFT);

var totalOffset = 0;
var xMovement = 0;

// Do the magic
for (var y = 0; y < numberOfRows(); y++)
{
totalOffset = 0;

for (var x = 0; x < numberOfCells(); x++)
{
if (x == 0)
{
xMovement = (rowShift) ? xOffset : 0;
}
else
{
xMovement = cellWidth + xOffset;
}

totalOffset += xMovement;

// Offset the layer into our Canvas "window"
layerRef.applyOffset(-(xMovement), 0, OffsetUndefinedAreas.WRAPAROUND);

saveCell(x,y);
};

// Offset the layer back to the left and down one row
layerRef.applyOffset(totalOffset, -(cellHeight + yOffset), OffsetUndefinedAreas.WRAPAROUND);

// Flip the rowShift. If it was true, make it false and vice versa.
rowShift = !rowShift;
};

// Calculate number of cells per row. May change depending in rowShift, etc
function numberOfCells()
{
var theWidth = imageWidth;

if (rowShift == true)
{
var theWidth = theWidth - xOffset;
}
return Math.floor((theWidth + xOffset) / (cellWidth + xOffset));
}

// Calculate number of rows
function numberOfRows()
{
return Math.floor((imageHeight + yOffset) / (cellHeight + yOffset));
}

// Pad the cell x and y numbers for proper sorting
function pad(num, size)
{
var s = "000000000" + num;
return s.substr(s.length-size);
}

// Actually save, or really "Save For Web" the cell
function saveCell(x, y)
{
var nname = dname + "_" + pad((x + 1), 3) + "_" + pad((y + 1), 3);

doc.exportDocument (new File(dir + "/" + nname + ".jpg"), ExportType.SAVEFORWEB, options);
}

// Reset the ruler units
app.preferences.rulerUnits = myRulerUnits;

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme