I am using TeXlive 2016 with LuaTeX. My TeX documents include images, which must be 8-bit flattened grayscale (no transparency) or 1-bit monochrome, in PNG format. I am good with graphics programs, and correctly prepare the images with proper model and resolution, finished using Magick mogrify -strip and verified with identify -verbose.

Apparently \includegraphics knows how to size an image at 100% scale, based on its pixels and resolution. It read the metadata, I assume. Now for my question: can \includegraphics (or some other command within LuaLaTeX, not shell) give a yes-no answer as to whether an image is really grayscale or monochrome? The images are always PNG.

My concern is that an unprocessed image (say in rgba model, using only gray shades) could accidentally be included. I do not expect TeX to convert the image or operate on it in any way. All I want is for it to be inspected. If not flattened gray or monochrome, then I'd write a warning message to the log. Then I'd know that I mistakenly included the wrong kind of image.

Possible, without reams of code? I have the PDF spec, but reading it is not for amateurs.

My question is broader than it might seem. Anyone preparing PDF for black and white print-on-demand would face similar issues. I realize that the images are not PNG within the PDF; but that is how they are input to TeX.

EDIT: After reviewing David's response, below, I looked at the image format in more detail. Something similar applies to JPG, but I will focus on PNG.

The PNG specification requires an IHDR chunk early in the file. The tenth byte after the string IHDR is a code for the image color model. A grayscale (or monochrome) image, without alpha channel, has hex code 00 there. Thus, if Lua has the ability to directly read the image file bytes, it should be able to scan for IHDR, count to ten, and report the byte.

Apparently that is NOT what Lua's img.colorspace does, since it always returns nil regardless of what PNG image (gray, color) I feed it. Either img.colorspace is not what I expect, or it tries but fails to get the right code.

\includegraphics (the latex macro) knows essentially nothing about the image. In classical tex the image file is never seen by tex at all.

In Luatex however you have the img lua library available which has the following information fields for an image

field name      type    description
attr            string  the image attributes for LuaTEX
bbox            table   table with 4 boundingbox dimensions llx, lly, urx and ury over-
ruling the pagebox entry
colordepth      number  the number of bits used by the color space
colorspace      number  the color space object number
depth           number  the image depth for LuaTEX
filename        string  the image file name
filepath        string  the full (expanded) file name of the image
height          number  the image height for LuaTEX
imagetype       string  one of pdf, png, jpg, jp2 or jbig2
index           number  the pdf image name suffix
objnum          number  the pdf image object number
page            number  the identifier for the requested image page
pagebox         string  the requested bounding box, one of none, media, crop, bleed, trim,
art
pages           number  the total number of available pages
rotation        number  the image rotation from included pdf file, in multiples of 90 deg.
stream          string  the raw stream data for an /Xobject /Form object
transform       number  the image transform, integer number 0..7
width           number  the image width for LuaTEX
xres            number  the horizontal natural image resolution (in dpi)
xsize           number  the natural image width
yres            number  the vertical natural image resolution (in dpi)
ysize           number  the natural image height
visiblefileame  string  when set, this name will find its way in the pdf file as PTEX specifi-
cation; when an empty string is assigned nothing is written to file;
otherwise the natural filename is taken


This probably (perhaps) has the information you need, but latex doesn't currently offer an interface to that through the latex graphics macros, you'd need to drop into Lua code.

The example captions each image with its monochrome status

\documentclass{article}
\usepackage{graphicx}
\begin{document}

\includegraphics{c1.png}

monochrome:
\directlua{
img1=img.scan{filename="c1.png"}
tex.print(tostring(img1.colordepth==1))
}

\includegraphics{m1.png}

monochrome:
\directlua{
img2=img.scan{filename="m1.png"}
tex.print(tostring(img2.colordepth==1))
}

\end{document}

• I knew that some day I would have to learn some Lua. So far, I merely copy and paste. This will provide the motivation. My method of coding involves sacrificing chickens by moonlight, and my rural neighbors are getting mighty suspicious about the number of foxes, so I have to keep a low profile with Lua. – user103221 Dec 28 '16 at 23:55
• @RobtA example coming up in edit – David Carlisle Dec 28 '16 at 23:57
• Excellent! The neighbors were already starting to mutter under their breaths, and I could hear their Rottweilers growling. – user103221 Dec 29 '16 at 0:06
• Further info: I played with the Lua code awhile, and also looked in the relevant Lua manual. The colordepth does indeed work well, distinguishing a 1-bit monochrome image from anything else. However, grayscale and rgb both return 8. That is, "per channel." There does not seem to be a way to discern the number of channels. The colorspace does not do that. Further Internet investigation suggests that it cannot be done this way, without linking to an external executable of the Magick sort. – user103221 Dec 29 '16 at 2:31
• @RobtA luatex is under active development if you think there is metadata in the image that you can not reach from luatex, it is worth asking on the luatex list to check it's not possible and/or put in a feature request – David Carlisle Dec 29 '16 at 12:10