I have many PNG screenshots with an identical piece of graphic in each of them. The piece has the same dimensions in all of the images.
What command line program can I use to find the position of it in each of the files (fed to one by one)?
The following is only a rough idea, no ready solution (especially no code!).
I would convert a sample of the small graphic and the screenshots to a raw (uncompressed) format (TGA has abolultely no compression, it's just a complete dump of every pixel) and then grep for the graphic in the screenshot file. Then calculate the position.
For the calculation you need the dimensions (width and height) of the images which you can get with Image Magick's identify command. That is:
GRAPHIC_WIDTH=$(identify -verbose graphic.tga | sed -n '/Geometry:/s%.*Geometry:\ \(.*\)x.*%\1%p') GRAPHIC_HEIGHT=$(identify -verbose graphic.tga | sed -n '/Geometry:/s%.*x\([^+]*\)+.*%\1%p') The first 18 bytes of a TGA file do not contain pixel information, so should be omitted:
tail -c +19 graphic.tga > graphic.colorinfo And, as in the comments from MatthewRock, you can’t grep for the whole graphic at once because it is saved line by line and surrounded by pixels from the screenshot, you should search linewise, i.e. search for the first pixel line of the graphic, and if that was found then search for the second line X pixels further, where X is the width of the screenshot minus the width of the graphic.
You should use grep with the option -F and a graphic file separated by new lines at K pixels, where K is the width of the graphic times its color depth in bytes. Do this with head and tail. If the colordepth is 8 bits then every pixel line is K bytes long, if the colordepth is higher, e.g. 24 bits or 3 bytes, the pixel line is K times 3 bytes long, etc.:
The 10th line that is 20 pixels long and has a colordepth of 3 bytes could be obtained in the following way:
head -c $((10*20*3)) graphic.colorinfo | tail -c 60 Of course there are cases where this approach would be somewhat complicated to write with shell code, e.g. if the screenshot is completely unicolored white (and the graphic, too), and the graphic only has one black pixel.
The idea is to save temporary start coordinates (position of left most and top most pixel where the first line matches) and from there search the lines below until one line does not match, then start from the next matching first line, etc.
Finally I have to say that it would be much easier to do it on a byte level (not work on images with text tools), such as a hexeditor. Or even better use C or python. But the approach would be the same (searching for matching lines).
.png