Remove pixels next to a particular color

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
cookmeplox
Posts: 3
Joined: 2014-04-28T10:36:10-07:00
Authentication code: 6789

Remove pixels next to a particular color

Post by cookmeplox »

I have a bunch of icons that look something like this. I would like to remove any pixels that are the color #212121, that are also 8-connected (directly north, south, east, west, north-west, south-west, north-east or south-east) to any pixels that are either #080808 or #070707. It would look like this afterwards. Generally, I want to remove pixels if they are a certain color, and are touching pixels of another certain color. I've looked a bit into morphology, but I haven't figured out how to also add the color-related rules.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Remove pixels next to a particular color

Post by snibgo »

Pixels can't be "removed". Perhaps you mean "make transparent".

This is a complex problem, but not difficult if you break it down into sub-problems. What have you done so far? Have you broken it down? What parts are giving you problems?
snibgo's IM pages: im.snibgo.com
cookmeplox
Posts: 3
Joined: 2014-04-28T10:36:10-07:00
Authentication code: 6789

Re: Remove pixels next to a particular color

Post by cookmeplox »

Sorry, yes, I am referring to making those pixels transparent. I'm really not sure how to approach the problem -- the images are small enough that I could just go pixel by pixel. Or perhaps I could list all pixels that are neighboring the #080808/#070707 pixels somehow, and then see how many of those are #212121...I'm really not sure.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Remove pixels next to a particular color

Post by snibgo »

I would break it down like this:

We need to make some pixels transparent. Which pixels? Only those that are (a) #212121 and (b) 8-connected to a pixel that is either #080808 or #070707. All other pixels must retain their existing transparency.

"Doing some action to some set of pixels" is often done with a mask. I'll use the convention that white means the pixel is in the set, or black means outside the set.

We can easily find the set of pixels that are a certain colour, eg #212121 or #080808, or are already transparent, or whatever.

As you have realised, "-morphology" can find adjacency. "Square:1" finds 8-connected adjacency.

Then it's just a question of combining sets of pixels. Making the result the lightest from a pair of images is equivalent to finding pixels that satisfy EITHER condition 1 OR condition 2. Making the result the darkest is equivalent to finding pixels that satisfy BOTH condition 1 AND condition 2

Combining these thoughts gives the following Windows BAT script. Adjust for other languages. Don't worry about %IM%; that's just for my computer. The commands could be rolled together into single command with no intermediate files. The result is n6.png, which is identical to your desired result.

Code: Select all

rem What pixels are either #080808 or #070707?
%IM%convert ^
  P6Cl54N.png ^
  -background Black -flatten ^
  -fill Black -opaque White ^
  ( -clone 0 -fill Black +opaque #080808 -fill White -opaque #080808 ) ^
  ( -clone 0 -fill Black +opaque #070707 -fill White -opaque #070707 ) ^
  -delete 0 ^
  -compose Lighten -composite ^
  n.png

rem What pixels are adjacent to pixels that are either #080808 or #070707, or are those pixels?
%IM%convert ^
  n.png ^
  -morphology Dilate Square:1 ^
  n1.png

rem What pixels are #212121?
%IM%convert ^
  P6Cl54N.png ^
  -background Black -flatten ^
  -fill Black +opaque #212121 -fill White -opaque #212121 ^
  n2.png

rem What pixels are #21212 AND adjacent to pixels that are either #080808 or #070707?
rem These need to be made transparent.
%IM%convert ^
  n1.png ^
  n2.png ^
  -compose Darken -composite ^
  n3.png

rem What pixels are already transparent?
%IM%convert ^
  P6Cl54N.png ^
  -alpha Extract ^
  -negate ^
  n4.png

rem What pixels need to be made transparent OR are already transparent?
%IM%convert ^
  n3.png ^
  n4.png ^
  -compose Lighten -composite ^
  n5.png

rem Make the correct pixels transparent.
%IM%convert ^
  P6Cl54N.png ^
  ( n5.png -negate ) ^
  -compose CopyOpacity -composite ^
  n6.png
snibgo's IM pages: im.snibgo.com
cookmeplox
Posts: 3
Joined: 2014-04-28T10:36:10-07:00
Authentication code: 6789

Re: Remove pixels next to a particular color

Post by cookmeplox »

Thank you very much! That's exactly what I was looking for. For future reference, is it possible to do this kind of thing without actually saving all the temporary files?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Remove pixels next to a particular color

Post by snibgo »

Yes. The commands could be rolled together into single command with no intermediate files. That would make it much faster.

When I'm trying to solve complex image processing problem, I break it down into stages, solve each stage as a single command, and put them in a script. When I've tested it for a while and I am convinced it works, I combine the commands and eliminate intermediate files.

Try combining them yourself. Just do one at a time. For example, n.png is used only to create n1.png. You can easily combine these two commands together, so it doesn't create n.png.
snibgo's IM pages: im.snibgo.com
Post Reply