Determining if All Pixels Fall Within a Color Range

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?".
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Determining if All Pixels Fall Within a Color Range

Post by snibgo »

I misunderstood what you want for (3). I think you want the answer to be "yes" if, and only if, the image contain no near-white pixels, and is not entirely near-black.

These conditions are equivalent to: maximum lightness is less than 98%, and more than 2%.

Code: Select all

convert ^
  %SRC% ^
  -colorspace Gray ^
  -format "%%[fx:maxima>0.02&&maxima<0.98?1:0]" ^
  info:
snibgo's IM pages: im.snibgo.com
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

Yes, as long as the grays are within the RGB range (0-255,0-255,0-255)).

Let me explain this a little further. I print full-color designs on shirts. Shirts print with CMYK inks (for all intents and purposes, it could be RGB inks). Since white is the absence of all colors in CMYK colorspace (0,0,0,0), there is no way to print white with the inks. Think of it this way: you cannot print white on your inkjet printer.

Therefore, IF the art utilizes ANY white pixels I need to pass the shirt through a separate process that lays down white ink separately.

Since I'm printing on fabric, the ink absorbs, which ultimately causes a color shift. On lighter color shirts, it's no problem, but on dark shirts the colors lose their fidelity. To combat the color shift on dark shirts, I will also print a white layer underneath the color layer. It's commonly called an under-base, and when used, the colors sit on top of white ink layer, and voila.

There is, though, a unique circumstance. If the art is completely black, the color won't shift, so regardless of the shirt color, I will NEVER print white ink with an all-black design.

So, there are my 3 scenarios:

1) Uses ANY white ink. I MUST ALWAYS under-base.
2) Completely black. I'll NEVER need to under-base.
3) Something else (potentially a combination of many colors, including white and black). If it contains white, condition 1 supersedes; otherwise, under-base use is a function of the shirt color.

Make sense?

So that's the goal. Determining "always", "never", or "per shirt color".
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Determining if All Pixels Fall Within a Color Range

Post by fmw42 »

snibgo's modified code should do that.

1) near white

2) near black

3) anything else
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Determining if All Pixels Fall Within a Color Range

Post by anthony »

An alternative for 3 is to -solarize the image at 50% That make pure white, pure black (folding the colorspace in half) As such is any pixels after a solarize is more than 2% away from black, you have grey pixels.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

Thanks. I tried it and didn't get any result like I anticipated. In the VB world, I typically compose like this:

Code: Select all

 objMi.Convert "-profile", "C:\ColorMatchRGB.icc", myimagename, "-sample", "800x", "PNG32:C:\newimage.png"
or

Code: Select all

imagedata = objMi.Identify("-units", "PixelsPerInch", "-format", "%x %y %w %h", myimagename)

The former performs an action on the file, and the latter provides a variable output. I attempted to compose per your description:

Code: Select all

MaxColorValue = objMi.Convert(myimagename, "-colorspace", "Gray", "-format", "%%[fx:maxima>0.02&&maxima<0.98?1:0]")
I also tried:

Code: Select all

MaxColorValue = objMi.Identify(myimagename, "-colorspace", "Gray", "-format", "%%[fx:maxima>0.02&&maxima<0.98?1:0]")

The result was null. What data TYPE of value would normally be returned with the INFO: request?

Is there a more simple way? To identify the brightest pixel within the image file? I guess if it's 2%, it's all black. If it's >98% it contains white, if it's anything else it's in the middle. I would anticipate something like this:

Code: Select all

MaxColorValue = objMi.Identify(myimagename, "-BrightestPixel")
In retrospect, it seems like that should be the easiest way to accomplish this.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Determining if All Pixels Fall Within a Color Range

Post by snibgo »

I showed you syntax for Windows BAT, where "%" is a special character, so it needs to be doubled.

Your VBA examples "%x %y %w %h" don't double the percent.

So don't double it in "%[fx:maxima>0.02&&maxima<0.98?1:0]"
snibgo's IM pages: im.snibgo.com
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

Thanks. I'm still not getting a response, but I'll keep working on it and let you know if it ever works.

Just figured there was an easier way to just find the "maxbright" pixel (or max R, max G, max B).

News to follow...
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

Well, I solved it, but it's a little cumbersome. Since I wasn't getting any response from the function, I took a different approach that you guys kind of touched on. Here's my solution:

1) Convert to grayscale
2) Convert back to RGB
3) Run a histogram export (since R=G=B), there is a max of 256 data points, and the respective pixel counts.
4) I sum the count of all pixels within the white range, black range, and everything else.

At that point, I can use basic if/then to determine the answer.

Code: Select all

objMi.Convert myimage, "-colorspace", "gray", "c:/newimage.png"
objMi.Convert "c:/newimage.png", "-type", "TrueColorMatte", "-define", "png:color-type=6", "c:/newimage.png"
objMi.Convert "c:/newimage.png", "-colors", "256", "-format", "%c", "histogram:info:C:/pixel_info.txt"
I suppose I could concatenate and/or clean up these commands, but it works. My dad always taught me, "If it ain't broke, don't fix it."

Thank you very much, guys, for your guidance!
Post Reply