Copy link to clipboard
Copied
Hi, I'm trying to record a Photoshop action to break apart a very large image into small square images and name them according to their grid number/letter. I did the first two rows for an example. Can you help me to develop an easier or better way to do this?
I will be using this to break apart various sizes of images into tiles to create large tile wall murals. We print the individual files onto ceramic tile so we need to name the files according to the grid so the installers will know which tile goes where on the wall. These tiles are 12in x 12in square. The large grid file is 26ft wide by 26ft tall. I will open the mural file and place it into this Photoshop file and size it to the size of the mural on the grid. When we run the script there will be a lot of blank tiles we won't need and will just delete.
Please see images which i have created via my record action and here is my action file for review please.
Thanks in advance
Copy link to clipboard
Copied
I believe you will have a hard time developing an action to handle different size documents. If all your Document have a square aspect ratio 1:1 you may be able to record square selections that are a percentage of the documents equal with and height brake the image into square tiles layers. and the export layer to files. If your images have different aspect ratios you would need to use Photoshop scripting to cut up your images and it you want to use a 12" x 12" tiles the Aspect ratio side need to be some multiple of 12.
x12 by y12 that is x feet by y feet. A script can use logic to look at the a document canvas size in pixels and its resolution to see if the a document sides are a multiple of 12". Actions can not use logic they are hard coded steps.
If a document is a correct size a script could easily create the 12" x 12" tile document you need. With file names like ImageName+Row#+Column#.jpg.
Copy link to clipboard
Copied
Assuming you have all Guides already set-up and have one layer in PSD file.
Script cuts image into small peaces defined by Guides and names them according to their grid number/letter. Rows are named with numbers [0-9] and columns by letters [A-Z]. Each slice is saved as PNG file with original name + grid number&letter.
Have one layer in the file. Add bunch of Guides. Save file as PNG and run the script. Enjoy the rest of your day!
Use it on your own risk.
https://bitbucket.org/snippets/rendertom/6Angy
(function() {
try {
#target photoshop
if (app.documents.length === 0)
return alert("Open file first");
var doc = app.activeDocument;
if (doc.layers.length !== 1)
return alert("This script can handle only one layer in file. Merge your layers and run script again.");
var originalRulerUnits = app.preferences.rulerUnits,
plot = plotDocument(),
selectionCoordinates = [],
newLayer, newDocument,
layer = doc.layers[0];
app.preferences.rulerUnits = Units.PIXELS;
app.displayDialogs = DialogModes.NO;
layer.isBackgroundLayer && layer.isBackgroundLayer = false;
layer.selected = true;
doc.selection.deselect();
for (var i = 0, il = plot.length; i < il; i++) {
selectionCoordinates[0] = [plot.x, plot.y];
selectionCoordinates[1] = [plot.x, plot.y + plot.height];
selectionCoordinates[2] = [plot.x + plot.width, plot.y + plot.height];
selectionCoordinates[3] = [plot.x + plot.width, plot.y];
doc.selection.select(selectionCoordinates);
if (selectionHasPixels()) {
newLayer = layerViaCopy();
newLayer.name = plot.name;
duplicateToNewDocument(newLayer)
app.activeDocument.trim(TrimType.TRANSPARENT);
savePNG(File(doc.path + "/" + getBaseName(doc) + "-" + plot.name + ".psd"));
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
app.activeDocument = doc;
newLayer.remove();
}
}
app.preferences.rulerUnits = originalRulerUnits;
alert("done")
/////// HELPER FUNCTIONS ///////
/**
* Converts document Guides information to array of coordinates blocks
* @return {[Array]} [Array of objects, containing x, y, width, height, name properties]
*/
function plotDocument() {
var guidesArray = getGuidesCoordinates(),
coords = [],
vStart, vCurrent = vMin = 0,
hStart, hCurrent = hMin = 0,
columnName = "";
if (guidesArray.vertical[0] !== 0)
guidesArray.vertical.unshift(0);
if (guidesArray.vertical[guidesArray.vertical.length - 1] < Number(app.activeDocument.width))
guidesArray.vertical.push(Number(app.activeDocument.width))
if (guidesArray.horizontal[0] !== 0)
guidesArray.horizontal.unshift(0);
if (guidesArray.horizontal[guidesArray.horizontal.length - 1] < Number(app.activeDocument.height))
guidesArray.horizontal.push(Number(app.activeDocument.height))
for (var h = 1, hl = guidesArray.horizontal.length; h < hl; h++) {
hStart = hCurrent;
hCurrent = guidesArray.horizontal
; vCurrent = guidesArray.vertical[0];
vMin = guidesArray.vertical[0];
columnName = "a";
for (var v = 1, vl = guidesArray.vertical.length; v < vl; v++) {
vStart = vCurrent;
vCurrent = guidesArray.vertical
; coords.push({
x: vStart,
y: hStart,
width: vCurrent - vMin,
height: hCurrent - hMin,
name: h + columnName
});
vMin = vCurrent;
columnName = String.fromCharCode(columnName.charCodeAt(0) + 1).toString();
}
hMin = hCurrent;
}
return coords
}
/**
* Creates object with vertical/horizontal arrays that contain Guides coordinates
* @return {[Object]} []
*/
function getGuidesCoordinates() {
var docGuides = app.activeDocument.guides,
verticalGuides = [],
horizontalGuides = [];
for (var g = 0, gl = docGuides.length; g < gl; g++) {
if (docGuides
.coordinate >= 0) { if (docGuides
.direction === Direction.VERTICAL && docGuides .coordinate <= Number(app.activeDocument.width)) { verticalGuides.push(Number(docGuides
.coordinate)) } else if (docGuides
.direction === Direction.HORIZONTAL && docGuides .coordinate <= Number(app.activeDocument.height)) { horizontalGuides.push(Number(docGuides
.coordinate)) }
}
}
return {
vertical: removeDuplicatesFromArray(verticalGuides).sort(),
horizontal: removeDuplicatesFromArray(horizontalGuides).sort()
}
}
/**
* Removes Dulpicates from array
* @param {[Array]} userArray [Array with values]
* @return {[Array]} [New array without duplicates]
*/
function removeDuplicatesFromArray(userArray) {
var seen = {},
out = [],
j = 0,
item;
for (var i = 0, il = userArray.length; i < il; i++) {
item = userArray;
if (seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
/**
* Checks if selection has live pixels
* @return {[Bool]} [True if selection contains pixels]
*/
function selectionHasPixels() {
try {
app.activeDocument.selection.copy();
return true
} catch (e) {
return null
}
}
/**
* Creates new layer via copy.
* @return {[Object]} [New layer]
*/
function layerViaCopy() {
app.activeDocument.selection.copy();
app.activeDocument.artLayers.add();
app.activeDocument.paste();
return app.activeDocument.activeLayer;
}
/**
* Duplicates selected layer to new document
* @param {[Object]} layer [Layer to duplicate]
* @return {[Object]} [Returns layer in new document]
*/
function duplicateToNewDocument(layer) {
var doc = app.activeDocument;
var newDocument = app.documents.add(doc.width, doc.height, doc.resolution);
app.activeDocument = doc;
var newLayer = layer.duplicate(newDocument, ElementPlacement.INSIDE);
app.activeDocument = newDocument;
newDocument.layers[newDocument.layers.length - 1].remove();
return newLayer;
}
/**
* Saves active document as PNG file with transparency
* @param {[Object]} saveFile [File Object with PNG extension]
* @return Nothing
*/
function savePNG(saveFile) {
var pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.compression = 9;
pngSaveOptions.interlaced = false;
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
};
/**
* Gets document name without extension
* @param {[Object]} document [Optional. Document to whos name to get]
* @return {[String]} [Document name without extension]
*/
function getBaseName(document) {
document = document || app.activeDocument;
return decodeURI(document.name.substring(0, document.name.lastIndexOf(".")));
}
} catch (e) {
alert(e.toString() + "\nScript File: " + File.decode(e.fileName).replace(/^.*[\|\/]/, '') +
"\nFunction: " + arguments.callee.name +
"\nError on Line: " + e.line.toString())
}
})();
Copy link to clipboard
Copied
Thanks Jarda Bereza​I have chekced your script this will make very squire 12x12in but not show numbers also show file name as started with Capture 1a etc...
Copy link to clipboard
Copied
1) Create slice across whole image
2) Calculate desired size in pixels
3) set divide slice like this:
4) file > export > save for web legacy
Should by quite fast. Could be actionable a run in batch.
Doesn't matter number of layers.