How to slice a rectangle shape, horizontally, into 3 equal sized shapes?
Copy link to clipboard
Copied
I'm trying to make a collage of three different images, using the clipping mask, but first I need my three separate shapes.
I've summised that the best way to do this is to evenly slice a rectangle shape into 3.
Can I find a way to do that though? Sometimes Photoshop can be the most unintuitive software.
Would appreciate advice from anyone that knows the solution to this, thank you.
NJ
Explore related tutorials & articles
Copy link to clipboard
Copied
PS. I've tried the Slice Select tool, right clicked on the shape and selected "3" horizontal but all this appears to do is create guides.
Copy link to clipboard
Copied
The slice tool is for saving a single image into separate "tiles" for recombining on a webpage using a HTML table.
Copy link to clipboard
Copied
Is this a vector shape layer (rectangle) or a pixel layer or something else? Can you post a cropped screenshot of the layers panel?
Copy link to clipboard
Copied
It's a vector shape. A basic rectangle. I need to create a shape to use as the clipping mask, right?
Copy link to clipboard
Copied
Does it have a stroke, or only a fill?
Copy link to clipboard
Copied
The following action will dupe/resize a vector shape layer into thirds.
Edit: I have updated the action for both rows and columns.
Select the vector shape rectangle and run the "Play - x3 Rows" or "Play - x3 Columns" conditional steps (highlighted in green below).
https://www.dropbox.com/s/w8q8nvceph5tr79/Split%20to%203%20Shapes.atn?dl=0
I might make a script for this, with a variable split quantity etc (the action with 3 fixed splits is quicker to create).
Copy link to clipboard
Copied
Just a fill. I could just create three separate rectangle shapes, but I'm then having to hope that they're all evenly sized. Surely there's a "split" or "divide" option that will create three vector shapes from one vector shape, no? Does this really need a script? It seems like such a basic thing, in my head at least.
Copy link to clipboard
Copied
I'll look into it but I can't recall an option to split/divide a single vector layer shape into two or more subdivisions. It's a hybrid layer and a path object...therefore the behaviour is more like a layer.
This is why I offered an action to automate the multiple manual steps of duplicating, resizing and aligning.
A script offers more possibilities than a static action.
Copy link to clipboard
Copied
Surely there's a "split" or "divide" option that will create three vector shapes from one vector shape, no? Does this really need a script? It seems like such a basic thing, in my head at least.
By IrishNJ
Photoshop is a raster application, not a vector application, and it excels in image editing. Adobe Illustrator is a vector application and this is a simple task there — with several methods to choose from. If you want to do it in PS, Stephen has kindly offered to write a script for you.
Jane
Copy link to clipboard
Copied
For comparison, here are the steps in Adobe Illustrator, a vector application:
- Select Rectangle
- Object menu > Path > Split Into Grid
- Number of Columns: 3
- OK
Unfortunately, there are a few more steps when you try it in Photoshop, a raster application.
Jane
Copy link to clipboard
Copied
There are several approaches to this. However, the Slice tool is not one of them, because it’s a very old tool specifically intended for creating slices for web page design, which is absolutely not a current web design practice. It won’t slice layers, the slice guides take effect only on the composite image on export.
There isn’t a function to split a vector shape into multiple equal shapes. With an existing vector shape rectangle, one approach is this, which is demonstrated below:
1. With the rectangle layer and the Move tool selected, in the options bar select any left edge reference point.
2. Choose Edit > Free Transform.
3. Disable Maintain Aspect Ratio (the link icon in the options bar), and set the W value to 33.33%. Now the rectangle is 1/3 of its former width.
4. (Optional) Choose Layer > New > Convert to Frame. This changes the rectangle into a rectangle frame, as if you had drawn it with the Frame tool. Now you don’t need to build a clipping mask.
5. Alt-drag (or Option-drag on Mac) to create a copy of the rectangle, and drag that to the right until it’s the distance you want from the first rectangle. Now there are two 1/3 width rectangles.
6. Repeat step 3 to create the second copy, so that you have three 1/3 width rectangles.
7. Add an image into each frame. I dragged them in from the desktop and dropped them into the frames, but if that doesn’t work on your computer, then with a frame layer selected, choose File > Place Embedded or File > Place Linked depending on how you want to import the image.
8. Repeat step 6 for the other two frames.
9. To reposition the images within the frames, make sure the frame content thumbnail is selected in the Layers panel and then drag within the frame. (If the frame thumbnail is selected, then the frame moves.)
10. If you didn’t do steps 3 and 4, now you build clipping masks.
Copy link to clipboard
Copied
Nicely done Conrad.
Copy link to clipboard
Copied
Thanks, but…I am now not totally comfortable with that solution, because it only works for a rectangle. If it was some arbitrary shape, you wouldn’t want to scale it disproportionately. So how to divide a vector mask path in Photoshop is still a really good question.
Then I saw @jane-e ’s example in Illustrator, and that got me thinking about another way. I remembered that Photoshop does have some (tragically obscure) path operations. So I came up with the technique demoed below, which works with a path of any shape, and you don’t need to do math or type any numbers. Short version: Use the path as a vector mask for a layer group containing the images. Add rectangle paths set up to subtract from the main vector mask path, then use Distribute Spacing on those rectangles to create the appearance that the main path was cut into equal divisions.
Long version:
1. The document has three image layers in a layer group, and a vector shape path that you want to cut into equal thirds. (If it’s a shape layer this won’t work, so cut and paste the shape layer’s path into a new path.)
2. Select the layer and then select the path, and in the Paths panel, Ctrl-click (Windows) or Command-click (Mac) the Add Layer Mask button. Holding down the modifier key changes the button to Add Vector Mask, so clicking it that way converts the path into a vector mask for the selected group. The images show through that mask. (You can also choose Layer > Vector Mask > Current Path.)
3. In the Paths panel, make sure the group’s Vector Mask path is selected, because you’re about to add paths to it.
4. Select the Rectangle tool, and in the options bar make sure it’s set to Path.
5. In the options bar, click the Path Operations menu, and make sure Subtract Front Shape is selected.
6. Drag the Rectangle tool to create a rectangle as wide as the gap you would like to see when the shape is divided up. Position this so that it’s almost touching the left edge of the vector mask path.
7. Alt-drag (Windows) or Option-drag (Mac) that rectangle to the right to make an offset copy of it, and drop it somewhere in the middle of the shape. It will be positioned more precisely later.
8. Repeat step 7 to copy and offset that rectangle two more times. Position the last one so that it almost touches the right edge of the vector mask path.
9. With the Path Selection tool, select all four rectangles, and in the options bar, click the Path Alignment menu, and click the Distribute Spacing button. This creates an equal amount of space between the four rectangle paths that are subtracted from the main vector mask path, so the main path looks like it was cut into three equal pieces. The images show through the three holes in the vector mask path.
10. Reposition or resize images as needed, behind the mask holes.
This is obviously something a beginner might not be able to figure out on their own. Photoshop doesn’t even make this kind of thing easy for advanced users. If you miss just one setting it doesn’t work, so I always get it wrong several times before I figure out the right way, even for this example. The power of paths and vector masks in Photoshop is under-appreciated; although they can be extremely powerful, the way they are set up makes them difficult to learn and master. But at least great things are possible.
Copy link to clipboard
Copied
Nicely done! The best questions are the ones that make us think of new approach, are they not? 🙂
The dialog in Illustrator also has an option for a gutter, and the paths can be copied into Photoshop. I'll still be doing it the easy way, but not everyone has a plan that includes Illustrator.
Jane
Copy link to clipboard
Copied
Here are two scripts, one for a variable quantity of rows, and another for columns.
I wanted to split to a grid, similar to the screenshot posted by @jane-e – however, I had some issues getting there with the step and repeat and thought it was better to post what I had so far. I'd be happy if somebody extended the script for splitting to a grid (with or without gutters)!
Rows:
/*
Split Rectangle Shape Layer to Rows.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-slice-a-rectangle-shape-horizontally-into-3-equal-sized-shapes/m-p/13676145
v1.0, 26th March 2023, Stephen Marsh
*/
#target photoshop
if (documents.length) {
if (activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {
// Get the shape layer name
var layerName = activeDocument.activeLayer.name;
function main() {
// To Do: Add code to check if the path is actually a square or rectangle...
// Save the current ruler units & set to px
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Loop the row input prompt until a number is entered
var rowInput;
while (isNaN(rowInput = prompt("This script is only intended for a square or rectangle shape layer!" + "\r" + "Row split quantity (enter a whole number):", 1)));
if (rowInput === null) {
alert('Script cancelled!');
return;
}
// Convert decimal input to integer
var inputToInteger = parseInt(rowInput);
// Final result
var rowQty = inputToInteger;
var layerBounds = activeDocument.activeLayer.bounds;
var layerHeight = layerBounds[3].value - layerBounds[1].value;
var rowHeight = layerHeight / rowQty;
var rowHeightPercent = 100 / rowQty;
// Group the active shape layer to contain the split layers
layerToGroup();
// Resize the base layer into a single row
freeTransform(0, 0, 100, rowHeightPercent);
// Dupe and move the row layers
if (rowQty > 1) {
for (var i = 0; i < rowQty - 1; i++) {
dupeLayer();
activeDocument.activeLayer.translate(0, -rowHeight);
}
}
// Select the group
activeDocument.activeLayer = activeDocument.activeLayer.parent;
// Ungroup hack to select all the split layers
ungroupLayer();
// Restore the original ruler units
app.preferences.rulerUnits = savedRuler;
}
activeDocument.suspendHistory("Split Rectangle Shape Layer to Rows...", "main()");
}
else {
alert("This script is only intended for vector shape layers!");
}
} else {
alert("A document must be open to run this script!");
}
///// FUNCTIONS /////
function freeTransform(horizontal, vertical, width, height) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
descriptor.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSCorner3")); // Lower left
descriptor2.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
descriptor2.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
descriptor.putObject(s2t("offset"), s2t("offset"), descriptor2);
descriptor.putUnitDouble(s2t("width"), s2t("percentUnit"), width);
descriptor.putUnitDouble(s2t("height"), s2t("percentUnit"), height);
descriptor.putEnumerated(s2t("interfaceIconFrameDimmed"), s2t("interpolationType"), s2t("bicubic"));
executeAction(s2t("transform"), descriptor, DialogModes.NO);
}
function dupeLayer() {
// DOM - activeDocument.activeLayer.duplicate();
// AM - Selects the duped layer, the DOM retains the source layer selection
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
descriptor.putList(s2t("ID"), list);
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
}
function layerToGroup() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass( s2t( "layerSection" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "from" ), reference2 );
descriptor.putString( s2t( "name" ), "Group #" );
executeAction(s2t( "make" ), descriptor, DialogModes.NO);
activeDocument.activeLayer.name = layerName + " - Split to Rows Group";
activeDocument.activeLayer = activeDocument.activeLayer.layers[0];
}
function ungroupLayer() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
executeAction( s2t( "ungroupLayersEvent" ), descriptor, DialogModes.NO );
}
Columns:
/*
Split Rectangle Shape Layer to Columns.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-slice-a-rectangle-shape-horizontally-into-3-equal-sized-shapes/m-p/13676145
v1.0, 26th March 2023, Stephen Marsh
*/
#target photoshop
if (documents.length) {
if (activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {
// Get the shape layer name
var layerName = activeDocument.activeLayer.name;
function main() {
// To Do: Add code to check if the path is actually a square or rectangle...
// Save the current ruler units & set to px
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Loop the column input prompt until a number is entered
var columnInput;
while (isNaN(columnInput = prompt("This script is only intended for a square or rectangle shape layer!" + "\r" + "Column split quantity (enter a whole number):", 1)));
if (columnInput === null) {
alert('Script cancelled!');
return;
}
// Convert decimal input to integer
var inputToInteger = parseInt(columnInput);
// Final result
var columnQty = inputToInteger;
var layerBounds = activeDocument.activeLayer.bounds;
var layerWidth = layerBounds[2].value - layerBounds[0].value;
var columnWidth = layerWidth / columnQty;
var columnWidthPercent = 100 / columnQty;
// Group the active shape layer to contain the split layers
layerToGroup();
// Resize the base layer into a single column
freeTransform(0, 0, columnWidthPercent, 100);
// Dupe and move the column layers
if (columnQty > 1) {
for (var i = 0; i < columnQty - 1; i++) {
dupeLayer();
activeDocument.activeLayer.translate(columnWidth, 0);
}
}
// Select the group
activeDocument.activeLayer = activeDocument.activeLayer.parent;
// Ungroup hack to select all the split layers
ungroupLayer();
// Restore the original ruler units
app.preferences.rulerUnits = savedRuler;
}
activeDocument.suspendHistory("Split Rectangle Shape Layer to Columns...", "main()");
}
else {
alert("This script is only intended for vector shape layers!");
}
} else {
alert("A document must be open to run this script!");
}
///// FUNCTIONS /////
function freeTransform(horizontal, vertical, width, height) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
descriptor.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSCorner3")); // Lower left
descriptor2.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
descriptor2.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
descriptor.putObject(s2t("offset"), s2t("offset"), descriptor2);
descriptor.putUnitDouble(s2t("width"), s2t("percentUnit"), width);
descriptor.putUnitDouble(s2t("height"), s2t("percentUnit"), height);
descriptor.putEnumerated(s2t("interfaceIconFrameDimmed"), s2t("interpolationType"), s2t("bicubic"));
executeAction(s2t("transform"), descriptor, DialogModes.NO);
}
function dupeLayer() {
// DOM - activeDocument.activeLayer.duplicate();
// AM - Selects the duped layer, the DOM retains the source layer selection
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
descriptor.putList(s2t("ID"), list);
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
}
function layerToGroup() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass( s2t( "layerSection" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "from" ), reference2 );
descriptor.putString( s2t( "name" ), "Group #" );
executeAction(s2t( "make" ), descriptor, DialogModes.NO);
activeDocument.activeLayer.name = layerName + " - Split to Columns Group";
activeDocument.activeLayer = activeDocument.activeLayer.layers[0];
}
function ungroupLayer() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
executeAction( s2t( "ungroupLayersEvent" ), descriptor, DialogModes.NO );
}
- Copy the code text to the clipboard
- Open a new blank file in a plain-text editor (not in a word processor)
- Paste the code in
- Save as a plain text format file – .txt (not .rtf)
- Rename the saved file extension from .txt to .jsx
- Install or browse the .jsx file to run (see the link below)
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html#Photoshop

