Copy link to clipboard
Copied
I am using the most recent version of photoshop (CC 2019) I want to slice an image into equal slices and then export the slices as separate files. I have found tutorials online on how to do this but they all use the "Save for the Web" feature that no longer exists in CC 2019. How do I export as separate files? If that option is not available is there some way I can split slices into different layers which could then be exported separated? Any help would be appreciated.
If you just open a smaller regular photo, is save for web still greyed out?
Thank you!
That worked as I hoped.
You chose the png options I wanted, too.
I appreciate your help!
Copy link to clipboard
Copied
@defaultmwout241jqs0 wrote:
I'm glad I found this script, but I would also like to adjust for the Export/Save for Web as PNG. Can you post your solution?
EDIT:
Here you go! As you didn't state your requirements, you can change the pngOptions as required...
//community.adobe.com/t5/photoshop/dividing-big-document-to-smaller-ones/m-p/9311087
// split image into x times y segments and save them as psds;
// 2017, use it at your own risk;
// 2020 - Modified by Stephen Marsh, adding prompts, save alert, saved doc test.
// 2021 - Modified by Stephen Marsh, changed output from PSD to Export Save for Web: PNG
#target photoshop
mainFunction();
function mainFunction() {
try {
activeDocument.path;
if (app.documents.length > 0) {
var originalUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Document;
var myDocument = app.activeDocument;
var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = myDocument.path;
var theCopy = myDocument.duplicate("copy", false);
// Loop the X input prompt until a number is entered
var theXinput;
while (isNaN(theXinput = prompt("(X) - Enter a whole number:", "3")));
// Convert decimal input to integer
var theXtoInteger = parseInt(theXinput);
// Final result
var theX = theXtoInteger;
// Loop the Y input prompt until a number is entered
var theYinput;
while (isNaN(theYinput = prompt("(Y) - Enter a whole number:", "3")));
// Convert decimal input to integer
var theYtoInteger = parseInt(theYinput);
// Final result
var theY = theYtoInteger;
var splitCount = theX * theY;
alert("The open image will be split into " + splitCount + " tiles and exported as PNG files...");
// Canvas Division
var xFrac = myDocument.width / theX;
var yFrac = myDocument.height / theY;
// PNG Options
var pngOptions = new ExportOptionsSaveForWeb();
pngOptions.PNG8 = false;
pngOptions.transparency = true;
pngOptions.interlaced = false;
pngOptions.quality = 100;
pngOptions.includeProfile = false;
pngOptions.format = SaveDocumentType.PNG;
// Create folder;
var folderName = thePath + "/" + theName + "_" + theX + "x" + theY;
if (Folder(folderName).exists === false) {
Folder(folderName).create()
}
// Export Save for Web PNG files;
for (var n = 1; n <= theY; n++) {
for (var m = 1; m <= theX; m++) {
cropTo((m - 1) * xFrac, (n - 1) * yFrac, m * xFrac, n * yFrac);
var theNewName = theName + "_" + bufferNumberWithZeros(m, 3) + "_" + bufferNumberWithZeros(n, 3);
theCopy.exportDocument((File(folderName + "/" + "_" + theNewName + ".png")), ExportType.SAVEFORWEB, pngOptions);
theCopy.activeHistoryState = theCopy.historyStates[0];
}
}
theCopy.close(SaveOptions.DONOTSAVECHANGES);
// Reset Original Ruler Units
app.preferences.rulerUnits = originalUnits;
}
// Pad Number with zeros
function bufferNumberWithZeros(number, places) {
var theNumberString = String(number);
for (var o = 0; o < (places - String(number).length); o++) {
theNumberString = String("0" + theNumberString)
}
return theNumberString
}
// Crop
function cropTo(x1, y1, x2, y2) {
// =======================================================
var desc7 = new ActionDescriptor();
var desc8 = new ActionDescriptor();
var idPxl = charIDToTypeID("#Pxl");
desc8.putUnitDouble(charIDToTypeID("Top "), idPxl, y1);
desc8.putUnitDouble(charIDToTypeID("Left"), idPxl, x1);
desc8.putUnitDouble(charIDToTypeID("Btom"), idPxl, y2);
desc8.putUnitDouble(charIDToTypeID("Rght"), idPxl, x2);
var idRctn = charIDToTypeID("Rctn");
desc7.putObject(charIDToTypeID("T "), idRctn, desc8);
desc7.putUnitDouble(charIDToTypeID("Angl"), charIDToTypeID("#Ang"), 0.000000);
desc7.putBoolean(charIDToTypeID("Dlt "), false);
desc7.putEnumerated(stringIDToTypeID("cropAspectRatioModeKey"), stringIDToTypeID("cropAspectRatioModeClass"), stringIDToTypeID("pureAspectRatio"));
desc7.putBoolean(charIDToTypeID("CnsP"), false);
executeAction(charIDToTypeID("Crop"), desc7, DialogModes.NO);
}
alert(splitCount + ' PNG Files saved to: ' + folderName);
} catch (err) {
alert('An image must be both open and saved before running this script!')
}
}
Copy link to clipboard
Copied
Thank you!
That worked as I hoped.
You chose the png options I wanted, too.
I appreciate your help!
Copy link to clipboard
Copied
I modified the above script to do a Save For Web behind the scenes for each image ONLY if the master document directory contains a "PNG" folder. You can modify the functions to suit your needs.
// split image into x times y segments and save them as psds;
// 2017, use it at your own risk;
// 2020 - Modified by Stephen Marsh, adding prompts, save alert, saved doc test.
#target photoshop
/* Start Unsaved Document Error Check - Part A: Try */
unSaved();
function unSaved() {
try {
activeDocument.path;
/* Finish Unsaved Document Error Check - Part A: Try */
/* Main Code Start */
if (app.documents.length > 0) {
var originalUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// document;
var myDocument = app.activeDocument;
var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = myDocument.path;
var theCopy = myDocument.duplicate("copy", false);
// Loop the X input prompt until a number is entered
var theXinput;
while (isNaN(theXinput = prompt("Enter a whole number:", "3")));
// Convert decimal input to integer
var theXtoInteger = parseInt(theXinput);
// Final result
var theX = theXtoInteger;
// Loop the Y input prompt until a number is entered
var theYinput;
while (isNaN(theYinput = prompt("Enter a whole number:", "3")));
// Convert decimal input to integer
var theYtoInteger = parseInt(theYinput);
// Final result
var theY = theYtoInteger;
// Canvas Division
var xFrac = myDocument.width / theX;
var yFrac = myDocument.height / theY;
// PSD options;
psdOpts = new PhotoshopSaveOptions();
psdOpts.embedColorProfile = true;
psdOpts.alphaChannels = true;
psdOpts.layers = true;
psdOpts.spotColors = true;
// create folder;
var folderName = thePath + "/" + theName + "_" + theX + "x" + theY;
if (Folder(folderName).exists === false) {
Folder(folderName).create()
}
// save PSD files;
for (var n = 1; n <= theY; n++) {
for (var m = 1; m <= theX; m++) {
cropTo((m - 1) * xFrac, (n - 1) * yFrac, m * xFrac, n * yFrac);
var theNewName = theName + "_" + bufferNumberWithZeros(m, 3) + "_" + bufferNumberWithZeros(n, 3);
theCopy.saveAs((new File(folderName + "/" + "_" + theNewName + ".psd")), psdOpts, true);
// Guy takes over
app.displayDialogs = DialogModes.NO;
main(myDocument, theNewName + ".psd");
// Guy stopped taking over
theCopy.activeHistoryState = theCopy.historyStates[0];
}
}
theCopy.close(SaveOptions.DONOTSAVECHANGES);
// reset;
app.preferences.rulerUnits = originalUnits;
}
////// buffer number with zeros //////
function bufferNumberWithZeros(number, places) {
var theNumberString = String(number);
for (var o = 0; o < (places - String(number).length); o++) {
theNumberString = String("0" + theNumberString)
}
return theNumberString
}
////// crop //////
function cropTo(x1, y1, x2, y2) {
// =======================================================
var desc7 = new ActionDescriptor();
var desc8 = new ActionDescriptor();
var idPxl = charIDToTypeID("#Pxl");
desc8.putUnitDouble(charIDToTypeID("Top "), idPxl, y1);
desc8.putUnitDouble(charIDToTypeID("Left"), idPxl, x1);
desc8.putUnitDouble(charIDToTypeID("Btom"), idPxl, y2);
desc8.putUnitDouble(charIDToTypeID("Rght"), idPxl, x2);
var idRctn = charIDToTypeID("Rctn");
desc7.putObject(charIDToTypeID("T "), idRctn, desc8);
desc7.putUnitDouble(charIDToTypeID("Angl"), charIDToTypeID("#Ang"), 0.000000);
desc7.putBoolean(charIDToTypeID("Dlt "), false);
desc7.putEnumerated(stringIDToTypeID("cropAspectRatioModeKey"), stringIDToTypeID("cropAspectRatioModeClass"), stringIDToTypeID("pureAspectRatio"));
desc7.putBoolean(charIDToTypeID("CnsP"), false);
executeAction(charIDToTypeID("Crop"), desc7, DialogModes.NO);
}
alert('PSD Files saved to: ' + folderName);
/* Main Code Finish */
/* Start Unsaved Document Error Check - Part B: Catch */
} catch (err) {
alert('An image must be both open and saved before running this script!')
}
}
function main(myDocument, fileName)
{
// Document path
var Path = myDocument.path;
if (!Path.exists)
{
return;
}
// Document name, adding underscores
var Name = fileName.replace(/\.[^\.]+$/, '').replace(/\s+/g, '_');
// Document extension
var Ext = decodeURI(fileName).replace(/^.*\./, '');
// If not a PSD file
if (Ext.toLowerCase() != 'psd')
{
return;
}
// Save file name inculding path
var SaveFile = new File(Path + "/PNG/" + fileName.toLowerCase() + ".png");
try
{
// Remove the PNG file if already exists.
if (SaveFile.exists)
{
SaveFile.remove();
}
var PNGFolderPath = new Folder(Path + "/PNG");
if(PNGFolderPath.exists)
{
// TRADITIONAL SAVE DIALOG
//SavePNG(saveFile);
// SAVE FOR WEB DIALOG
SaveForWebPNG(SaveFile);
}
}
catch(error)
{
alert("Guy's script is awesome, however not perfect. " + error);
}
}
function SavePNG(SaveFile)
{
var pngSaveOptions = new PNGSaveOptions();
activeDocument.saveAs(SaveFile, pngSaveOptions, true, Extension.LOWERCASE);
}
function SaveForWebPNG(SaveFile)
{
var sfw = new ExportOptionsSaveForWeb();
sfw.format = SaveDocumentType.PNG;
sfw.PNG8 = false; // use PNG-24
sfw.transparency = true;
app.activeDocument.exportDocument(SaveFile, ExportType.SAVEFORWEB, sfw);
}
/* Finish Unsaved Document Error Check - Part B : Catch */
Copy link to clipboard
Copied
Another option here, it uses scripting to save PSD tiles from slices, without using Export > Save for Web which has a 8192 pixel dimension limitation which will scale down larger images.
/*
// Divide my image to layers
// https://community.adobe.com/t5/photoshop-ecosystem-discussions/divide-my-image-to-layers/m-p/12467520
// Script for splitting multiple PSDs to defined slices
// https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-for-splitting-multiple-psds-to-defined-slices/m-p/12592481#M608089
*/
#target photoshop
var s2t = stringIDToTypeID,
AR = ActionReference,
AD = ActionDescriptor;
try {
try {
(r = new AR).putProperty(s2t('property'), p = s2t('layerID'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var id = executeActionGet(r).getInteger(p);
}
catch (e) { throw "No layer selected!\nOpen the document and select layer" }
try {
(r = new AR).putProperty(s2t('property'), p = s2t('slices'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var slices = executeActionGet(r).getObjectValue(p).getList(p);
}
catch (e) { throw "This version of photoshop does not have access to slices" }
(r = new AR).putProperty(s2t('property'), p = s2t('resolution'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var res = executeActionGet(r).getDouble(p);
(r = new AR).putProperty(s2t('property'), p = s2t('title'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var nm = executeActionGet(r).getString(p).replace(/\..+$/, '');
try {
(r = new AR).putProperty(s2t('property'), p = s2t('fileReference'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var pth = executeActionGet(r).getPath(p);
}
catch (e) { throw "File not saved!" }
for (var i = 0; i < slices.count - 1; i++) {
(r = new AR).putIdentifier(s2t('layer'), id);
(d = new AD).putReference(s2t('target'), r);
executeAction(s2t('select'), d, DialogModes.NO);
(r = new AR).putProperty(s2t('channel'), s2t('selection'));
(d = new AD).putReference(s2t('target'), r);
d.putObject(s2t('to'), s2t('rectangle'),
function (b, d) {
for (var i = 0; i < b.count; i++)
d.putUnitDouble(k = (b.getKey(i)), s2t('pixelsUnit'), b.getInteger(k))
return d;
}(slices.getObjectValue(i).getObjectValue(s2t('bounds')), new AD)
);
executeAction(s2t('set'), d, DialogModes.NO);
try {
(d = new AD).putString(s2t("copyHint"), "pixels");
executeAction(s2t("copyEvent"), d, DialogModes.NO);
(d = new AD).putClass(s2t("mode"), s2t("RGBColorMode"));
d.putUnitDouble(s2t("width"), s2t("distanceUnit"), 1 * 72 / res);
d.putUnitDouble(s2t("height"), s2t("distanceUnit"), 1 * 72 / res);
d.putUnitDouble(s2t("resolution"), s2t("densityUnit"), res);
d.putEnumerated(s2t("fill"), s2t("fill"), s2t("white"));
d.putInteger(s2t("depth"), 8);
d.putString(s2t("profile"), "sRGB IEC61966-2.1");
(d1 = new AD).putObject(s2t("new"), s2t("document"), d);
executeAction(s2t("make"), d1, DialogModes.NO);
(d = new AD).putEnumerated(s2t("antiAlias"), s2t("antiAliasType"), s2t("antiAliasNone"));
d.putClass(s2t("as"), s2t("pixel"));
executeAction(s2t("paste"), d, DialogModes.NO);
executeAction(s2t("revealAll"), new AD, DialogModes.NO);
executeAction(s2t("flattenImage"), undefined, DialogModes.NO);
(d = new AD).putObject(s2t("as"), s2t("photoshop35Format"), new AD);
d.putPath(s2t("in"), File(pth.path + '/' + nm + ' ' + ('0' + i).slice(-2) + '.psd'));
d.putEnumerated(s2t("saveStage"), s2t("saveStageType"), s2t("saveBegin"));
executeAction(s2t("save"), d, DialogModes.NO);
executeAction(s2t("close"), new AD, DialogModes.NO);
(r = new AR).putProperty(s2t('channel'), s2t('selection'));
(d = new AD).putReference(s2t('null'), r);
d.putEnumerated(s2t('to'), s2t('ordinal'), s2t('none'));
executeAction(s2t('set'), d, DialogModes.NO);
}
catch (e) { throw e + "\nScript cannot create layer from empty space!\nMake sure that current layer contains pixels in all slices." }
}
} catch (e) { alert(e) }
And another option here as well:
https://www.andrewnoske.com/wiki/Adobe_Photoshop_-_Scripts_Related_to_Montaging
Copy link to clipboard
Copied
Mostly this is because adobe haven't bothered to update save for web for high resolution displays and failed to include slices into the new export tool and expects its users to write code for the software they are already forking out £50+ for a month.
Copy link to clipboard
Copied
@Gr3gA wrote:
Mostly this is because adobe haven't bothered to update save for web for high resolution displays and failed to include slices into the new export tool and expects its users to write code for the software they are already forking out £50+ for a month.
Save for Web was a great feature when it came out with Photoshop 5.5 in 1999, but is now in legacy and has been replaced by Export As. I don't expect it to be updated, but do expect it to one day disappear (my opinion only).
In those days, websites used tables instead of CSS. The purpose of slices was to optimize each part of an image separately and then use html to pull them into a table to appear as one image.
I won't ask why you are using slices in 2023, but if you want better support for them, you might consider making a feature request to Adobe. When you start a new thread, tag it as Ideas instead of Discussions.
Jane
Copy link to clipboard
Copied
I was making an series of tiled images that work together as a series for the Apple store, not unlike a user here creating a set of tiled images for instagram. Wierdly the image size limit is taken from the source image and not the output size defined by the slices. You can use slices on an image with just about any dimensions...you just can't export them which seems a little short sighted not to mention a pain in the backside once you've spent time cutting the image up. If theres is another way of cutting up an image automatically exporting please inform us.
Copy link to clipboard
Copied
Slices and Export/Save for Web (Legacy) use old code, from a time when internet bandwidth and images were much smaller.
Save for Web does have in input limit, it will either take a long time and or throw an error message that the image is too big. I can't recall the limitations. For output, if the image is greater than 8192px it will be scaled smaller on output.
Anyway, there were multiple scripts posted earlier in the topic which can use the slice info to save without using Save for Web with it's known limitations.
If you just need to split an image into regular sized "tiles" without having more complex different sized slices, then there is also another scripted option for splitting and joining tiled images:
https://www.andrewnoske.com/wiki/Adobe_Photoshop_-_Scripts_Related_to_Montaging
Copy link to clipboard
Copied
Yeah thats a lot harder than it should be.
Copy link to clipboard
Copied
Nobody uses image slices or table-based layouts anymore.
Responsive web design dictates that whole images be used in multiple sizes to fit various user agents on smartphones, tablets, laptops, desktops, TVs, kiosks, stadium jumbotrons... Responsive layouts are styled with Cascading Stylesheets— also known as CSS code.
More about Responsive Images:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
Hope that helps.
Copy link to clipboard
Copied