Dilate the border pixels of a layer

Discussion of Photoshop Scripting, Photoshop Actions and Photoshop Automation in General

Moderators: Tom, Kukurykus

Nightshade

Dilate the border pixels of a layer

Post by Nightshade »

I'm trying to set up an automated workflow in Photoshop, but before I can get into the actual scripting of the part I'm stuck on, I need to nail down an algorithm for a very specific problem I have. What I'm trying to do is dilate/expand/grow the border of a layer by one pixel at a time, and this is turning out to be harder than I expected.

What I want to achieve:
I want to expand/dilate/grow/bleed each layer one pixel at a time - but only in the case where the area outside the layer is either black or transparent (either one works for me - but maybe transparent pixels are easier to search for?). It should look at the entire document and not just the active layer (although I am open to a solution where the algorithm work on a flattened image. I can separate the colors with another script later)

What I've tried:
Various types of blurring and clamping (using for instance, a Levels layer to clamp away the gradient), blurring and posterizing.
I've tried flattening the image, selecting all the padding (black pixels), filled with Content Aware -fill and posterized it back to 2 levels (this results in a jagged edge). I've tried a lot and the thing that gets the closest to what I want to achieve is the "Minimum" filter under "Filter > Other"
I've also tried various select/deselect/intersection algoritms and although these work, they are very slow. In the end I might end up running this operation up to 512 times so having a 10-step selection algoritm that fills and deletes color in the layers is going to be VERY slow.

Problem:
In a composite image, the Minimum filter will eat away the black - just as I want - but it will also blend colors (which I DON'T want).
So for example, a blue area and a red area separated by a 1px row of black will result in the black line turning magenta if I run "Minimum" 1px on it - because the red and the blue blends together.

And if I separate each color into individual layers - as in the workfile below - then there is another issue. Sure I can run Minimum 1px at each layer - one at a time - but then the layer order screws things over, with the top layer occupying more pixels than it should, bleeding over onto other color layers.

You see the problem here? I want to expand out each layer and want them to meet half-ways - eating away either black or transparent pixels - not grow over each other or blend pixels. I've looked at the Custom filter for this but can't come up with a solution that doesn't blend pixels.
This did sound like an easy problem at first but damn this is really starting to annoy me.


Example workfile:
http://www.speedyshare.com/nJESB/example.psd
(press the download link text at the top)
jcr6

Dilate the border pixels of a layer

Post by jcr6 »

So you want to dilate the outside edge of the black, leaving the non-black untouched?

Step 1 would be to make a selection of just the area outside of the selection, 1 pixel wide.

How?
1a. turn off the black - it's nice for illustrative purposes, but not for this
1b. stamp visible (make a new layer showing everything, including the voids) cmd-option-shift-E
1c. Layer > Layer Mask > From transparency.
(you now have a map of where there is stuff and where there isn't. this transparency mask is now selected, btw.)
1d. Select all, copy
1e. delete the layer mask
1f. PASTE -- this is a new layer with just the map
1g. Image > Adjustments > Threshold. (make it either 100% selected or not at all)
1h. DUPLICATE --
1i. Filter > Maximum R=1 (dilate the mask)
1j. invert
1j. set opacity to 50%
1k. merge down (cmd-E)
1l. Image > Adjustments > Threshold at 64
1m. Invert.
(we now have a map of where the growth should take place)
1n. load selection (cmd-option-shift-2) from the luminance
1o. delete layer
(now we've got the selection of the cusp on top of a composite copy of the image and can 'grow' into it)

2. A variety of growth methods come to mind, but first you have to fill it with something.

2a. Edit > Fill > 50% gray (this will be replaced)
2b. Filter > Median R=4 (you could get wide gray lines that were 2 wide in step 2a where stuff merged together)
(so now we've got something that is wrong, but suitable to do morphology with)
2c. Filter > Other > Maximum R=1
2d. Filter > Other > Minimum R=2
2e. Filter > Other > Maximum R=1

It isn't perfect, but this should grow your regions and leave something resembling their content in the outer boundaries.