I just came back from a family reunion in May, and we took our fair share of group photos to commemorate the event. Some people are fairly easy to pick out in group photos, other less so. Especially when you are extrapolating from other photographs of them from how many years before or since. Which made me think about how to isolate pictures of certain individuals to say, “this face, that’s definitely cousin Willy”.
Since I don’t actually have a cousin Willy, I don’t have any group photos that I can pick him out of. So I went looking for group photos on the web and quickly found this one of NASA astronaut group 15 (“The flying Escargots”).
And I decided I’d pick out the International Mission Specialists of this class, of which there are 4. The Canadian Dafydd Williams was easy to pick out, as was Michel Tognini standing behind him, and Takao Doi as they all had additional patch badges indicating their additional affiliations. Jean-Loup Chrétien however, wasn’t wearing no stinkin’ badge, that I could see.
And Now the Code
So I started tinkering with our ImageImport Sample app. The first thing I did was change the page dimensions to a portrait-oriented letter-size page.
And I made it so that the image is centered on the page, within conventional margins. The way I did this was by calculating a smaller rectangle from the page’s crop box:
And then figuring out how scale the image to make it fit into that rectangle. Basically, you scale the horizontal dimension to fit your horizontal space, and your vertical dimension to fit your horizontal space, and you pick the smaller of the scaling factor to apply to both dimensions. If you used a larger scaling factor, then part of the image would be outside of your box. Using the smaller scaling factor, one of the dimensions will be completely filled while there will be some play in the other dimension. If there isn’t, congratulations, you have the exact same scale factor for both dimensions.
Now for our International Mission Specialists, I figured out rectangles for their faces in terms of percent of the width and height of the image. I measured from an origin at the bottom left of the image. I used a spreadsheet to calculate these percentages because the tool I was using to measure my face rectangles (*cough* Acrobat *cough*) gave me my coordinates in inches from the top left.
For each row of this array, I first create a rect for where the cropped image is to land:
Then, just like CalculateFitToRect, I call CalcImagePlaceToClip. The code is very similar, but CalcImagePlaceToClip has some extra steps to go from Percentage’s of the Image’s dimension to a width or length in User units.
A key difference is how horizDisp and vertDisp are calculated; we want the bottom left of the to hold portion of the image described by the percentage values. Which means that the lower and to the left of the destination rectangle on the page.
We know that this will overflow the destination rectangle. But we deal with that by clipping. Now, we could do so with this:
But for faces of people, it makes more sense to crop the image using an ellipse:
The Final Result
One little thing to note is that a consequence of
is that all 5 images are using the same Image XObject resource embedded in the PDF. The same image is actually displayed 5 times. But each time it is with a different matrix and clipping path specified in the content stream.
The full code is here.
If you have any questions, comment below or contact us!