Copy link to clipboard
Copied
I like the simplicity of the slice tool along with the "Slices from Guides" option, BUT I need to be able to save these slices with the same print quality as the original file, but as a JPG. Is there a way to save a slice as print quality JPG (300 dpi+)?
2) Use a script to save (not export) the slices to PSD:The code could be modified to save directly to JPEG, or you could batch convert the PSD to JPEG.
I have modified the original script from @jazz-y to save directly to JPEG:
/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/can-slices-be-saved-at-300-ppi-in-photoshop/m-p/
...
Copy link to clipboard
Copied
@cjonesmn Slices are intended to be used for a web based workflow not high-res/print.
Why would you be producing hi-res graphics from slices?
Copy link to clipboard
Copied
The functionality of Slices could be used for any output. What I like about this feature is that within very few clicks I can setup columns, rows and bleeds and then click once to save these as slices that can be expoorted as jpgs. It saves alot of steps. What Adobe could easily do is add one more setting in the Export box that would allow users to keep the original file resolution intact.
Copy link to clipboard
Copied
Export and Save For Web are specifically intended for web/screen/mobile, where ppi is irrelevant. So it's stripped from the file altogether. That's not going to change. You're not going to get 300 ppi. You're not going to get any ppi.
It sounds like you should be using InDesign. That's where you set up bleed, page layout elements, crop marks and so on.
There's a lot of things Photoshop really isn't appropriate for, and this sounds like one of them.
Copy link to clipboard
Copied
I think the main problem is that slices are processed through the File > Export > Save for Web (Legacy) command, and that command does not embed ppi metadata.
The File > Save As / Save a Copy commands do embed ppi metadata, but…they can’t process slices.
So there does not seem to be a command that both preserves slices and embeds ppi metadata. Even though slices could potentially be useful for lots of things, when slices were originally coded it was probably assumed they were there only to support HTML image slices. Which, by the way, are no longer the recommended way to do that in web design (CSS layers are now the recommended way, for very good reasons), so Adobe might be thinking they’re never going to look at that slice code again.
However, there is nothing wrong with asking Adobe to look at that Slice tool code again and upgrade it to no longer be focused on obsolete HTML image slicing, so that slices could be used to divide image output for any medium (like print or video). To submit that kind of feature request, post it in the Ideas section of this community. If you’re lucky, other people will vote it up, and if it gets enough attention Adobe may attach a status to a feature request, such as Under Review, In Progress, or Released.
Edit: It just occurred to me that there is no reason you actually need ppi metadata in the images, so here is one possible workaround:
1. Make sure the document has the pixel dimensions required to reach the correct effective resolution at the target print size. If that doesn’t make any sense, see the example below.
2. Using File > Export > Save for Web (Legacy), make sure all slices are set to export JPEG at High Quality; remember that each slice can be selected and set to different options, so make sure they are all set the same way.
3. Export with slices. The reason this should be OK is that if the document has enough pixels for print, you will get all those pixels when you export. The only thing missing is the ppi metadata.
4. Assemble for print. As long as all slices are sized so that they achieve an effective resolution of 300 ppi, it will print fine, you won’t need ppi metadata in the slice images themselves.
Example:
You want a document to print 10 inches wide at 300 ppi, and you want to export slices to be re-assembled in another document.
That means the original document has to be 3000 pixels wide (10 inches * 300 ppi).
1. Make a document 3000 pixels wide, and slice it up as needed.
2. Using File > Export > Save for Web (Legacy), export all slices as high quality JPEG.
3, Reassemble in whatever application you want to use to print them (InDesign, Illustrator, another Photoshop document). But make sure that the width of the reassembled image, in inches, is 10 inches wide.
4. Because the reassembled image is 10 inches wide, its 3000 pixels will divide across those 10 inches into 300 pixels per inch, so you will achieve 300 ppi even if there is no ppi metadata in the images.
Another method, if you plan to print directly from Photoshop, is to not use slices at all:
1. Make a document at the dimensions (in inches) and resolution (in ppi) that you need.
2. Lay down guides as needed.
3. With the Rectangular Marquee tool, draw a rectangular selection for what would normally be the first slice. It should snap to your guides, if View > Snap and View > Snap to > Guides are both enabled.
4. Choose File > Print.
5. In the Print dialog box, scroll down and enable Print Selected Area.
6. Print.
7. Repeat steps 3 through 6 for the other “slices.”
Copy link to clipboard
Copied
Thanks Conrad. I actually don't print thru Photoshop. What I do is prepare these files and then send them off to a professional printer. I've explored all of the workarounds you've mentioned. That said, from an efficiency perspective, nothing beats the Slice tool, but it's of no use to me as it currently exists. If Adobe could get around the DPI save limitation they'd probably find a whole new goup of followers for it.
Copy link to clipboard
Copied
If you’re sending them to a professional printer, how do they know how large to print each file? Are they inserted into one of their existing templates so that the size is already defined, or are you ordering each print individually from a predefined list of their sizes? Or, is each image a custom print job?
The reason I ask is that, especially if it’s one of the first two (you are using sizes they have already locked down), then ppi still doesn’t matter because the print will not deviate from that ordered size. If the print is going to fulfill an order where you selected a 10 inch wide print, and you give them 3000 pixels wide, once again it will print 300 ppi even if no ppi metadata is in the file, so you can just use the Slices feature as is.
Although adding ppi metadata is useful for indicating the final size of an image, it shouldn’t be relied on as guaranteeing that. For example, there are people who post here because an image doesn’t have enough detail even though it says “300 ppi.” That’s because it’s 300 ppi at like 3 inches or 5 inches, and they wanted to print it 10 inches so it’s not enough pixels even though it says “300 ppi.” So again, the ppi metadata alone is not a reliable enough guarantee of the final print size, and is not even necessary. What is actually necessary is having the correct number of pixels for the correct number of printed inches, and that is possible to supply through Save for Web because it can preserve all of the pixels in the document, if Scaling is 100%.
Whether slice export includes ppi metadata or not doesn’t affect or fix a document incorrectly set up for print. If the document itself has the wrong Image Size specs, slice export with ppi won’t make that any better, and if the document has the right Image Size specs, slice export without ppi won’t make that any worse. Because ppi metadata is not what determines success, pixel dimensions vs. print inches is what does.
If ppi metadata is absolutely required for some reason, then slice export can still be used, as long as the correct pixel dimensions are being exported, and something like Stephen’s script can embed the desired ppi metadata number, and then it’s all good.
And again, I’m not against slices, and would support Adobe making them more useful than just for web images. In other words I really do hope you get what you want them to do. I’m just thinking that missing ppi metadata is probably not a deal breaker here, as long as the required pixel dimensions are present in each image.
Copy link to clipboard
Copied
If you would like to use slices and have resolution metadata, then I have two scripted options for you:
1) Set the resolution metadata via a script in the exported JPEG files (not suitable for GIF or PNG):
Copy link to clipboard
Copied
Thank you Stephen... a scripting solution is pretty much the route I had to do (based on a few of your prior posts about this ;-)). What I need now is a way to create a gutter or bleed at each "slice" location. I'm sure I can do this with more scripting... it would just be nice to have something like the Slice tool that makes all of this so much easier.
Copy link to clipboard
Copied
If you are happy with the slice tool, then both of my suggested scripts will let you continue to use the slice tool and also have the resolution metadata. I'm not sure about the gutter but if that is a slice then it too would also be included.
Copy link to clipboard
Copied
Hmmm, I guess I'm unsure if the adding of missing resolution metadata would work for the printers I send my work to? I'll need to check with them, but it would be great to just have something that can be done more efficiently.
Copy link to clipboard
Copied
Hmmm, I guess I'm unsure if the adding of missing resolution metadata would work for the printers I send my work to? I'll need to check with them, but it would be great to just have something that can be done more efficiently.
By @cjonesmn
Why wouldn't it? It just contains the missing resolution info that Save for Web strips out.
Copy link to clipboard
Copied
Is the file is downsized to a web quality resolution on Export? If so then changing the metadata afterwards won't change it back to a true 300 DPI file, will it?
Copy link to clipboard
Copied
An image doesn't "have" a ppi. The image is just pixels, and it can be any ppi, or no ppi at all, without changing the file in the slightest. Ppi is just metadata.
Pixels per inch. It means exactly what it says, it explains itself.
As long as you don't resample the pixel data, you can assign any ppi you want. It just changes the print size, not the pixels.
Copy link to clipboard
Copied
Thank you. I actually pulled that from a post dated back to 2018 without thinking. I think we all know that print is DPI. I just corrected the title to DPI.
Copy link to clipboard
Copied
No, you still misunderstand. Dots per inch has nothing to do with this. The term dpi is used incorrectly by a lot of people. This is pixels per inch, and what I wrote above is how it works.
Copy link to clipboard
Copied
My question is in regard to print quality.
Copy link to clipboard
Copied
2) Use a script to save (not export) the slices to PSD:The code could be modified to save directly to JPEG, or you could batch convert the PSD to JPEG.
I have modified the original script from @jazz-y to save directly to JPEG:
/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/can-slices-be-saved-at-300-ppi-in-photoshop/m-p/14272292
v1.0 - 2nd December 2023, Stephen Marsh
Based on a script from jazz-y
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-for-splitting-multiple-psds-to-defined-slices/m-p/12592481
https://community.adobe.com/t5/photoshop-ecosystem-discussions/divide-my-image-to-layers/m-p/12467520
*/
#target photoshop
///// ADDITION TO ORIGINAL CODE - START /////
activeDocument.save();
activeDocument.flatten();
///// ADDITION TO ORIGINAL CODE - END /////
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);
///// ADDITION TO ORIGINAL CODE - START /////
var actDesc = new ActionDescriptor();
var idextendedQuality = stringIDToTypeID("extendedQuality");
actDesc.putInteger(idextendedQuality, 12); // 0-12
(d = new AD).putObject(s2t("as"), s2t("JPEG"), actDesc, new AD);
d.putPath(s2t("in"), File(pth.path + '/' + nm + ' ' + ('0' + i).slice(-2) + '.jpg'));
d.putEnumerated(s2t("saveStage"), s2t("saveStageType"), s2t("saveBegin"));
executeAction(s2t("save"), d, DialogModes.NO);
///// ADDITION TO ORIGINAL CODE - END /////
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)
}
///// ADDITION TO ORIGINAL CODE - START /////
executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);
///// ADDITION TO ORIGINAL CODE - END /////
Copy link to clipboard
Copied
Thank you soooo much for this modified script. It has been a life saver!!! I know this is a long shot but any idea if overlap of each slice can be added script? Some images I split need to have the slices overlap the slice next to it. Sometimes up to 1.5". Thanks for your help!!
Copy link to clipboard
Copied
The script facilitates working with existing slices, as they are. The onus is on the user to create the slices correctly.
Copy link to clipboard
Copied
This is great, for me it is saving the slices in reverse order, so if I have 4 user-defined slices, the first one saved as 'filename 00' is the content that was in slice 4. is there a way to not have this happen? as far as I can see the slices are correctly set up.
Copy link to clipboard
Copied
Try this updated code:
/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/can-slices-be-saved-at-300-ppi-in-photoshop/m-p/14272292
v1.1 - 19th December 2024, Stephen Marsh
Based on a script from jazz-y
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-for-splitting-multiple-psds-to-defined-slices/m-p/12592481
https://community.adobe.com/t5/photoshop-ecosystem-discussions/divide-my-image-to-layers/m-p/12467520
*/
#target photoshop
activeDocument.save();
activeDocument.flatten();
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!"
}
// Create an array to store slice information for sorting
var sliceInfo = [];
for (var i = 0; i < slices.count - 1; i++) {
var bounds = slices.getObjectValue(i).getObjectValue(s2t('bounds'));
sliceInfo.push({
index: i,
bounds: bounds,
x: bounds.getInteger(bounds.getKey(0)), // left position
y: bounds.getInteger(bounds.getKey(1)) // top position
});
}
// Sort slices by X first (left to right), then by Y (top to bottom)
sliceInfo.sort(function (a, b) {
if (a.x !== b.x) {
return a.x - b.x;
}
return a.y - b.y;
});
// Process slices in the sorted order
for (var i = 0; i < sliceInfo.length; i++) {
var sliceIdx = sliceInfo[i].index;
(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(sliceIdx).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);
var actDesc = new ActionDescriptor();
var idextendedQuality = stringIDToTypeID("extendedQuality");
actDesc.putInteger(idextendedQuality, 12);
(d = new AD).putObject(s2t("as"), s2t("JPEG"), actDesc, new AD);
d.putPath(s2t("in"), File(pth.path + '/' + nm + ' ' + ('0' + (i + 1)).slice(-2) + '.jpg'));
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)
}
executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);