I have to write a CGPDFContext. This PDF contains just one image.
The image has 2100 x 3000 pixels.
Suppose I open this image on Photoshop and print it at 300 dpi. Photoshop will use 300 pixels to build every inch of printed material, so this image will have 7 x 10 inches.
This image has this size because of that.
Now I have to create a CGPDFContext. I read somewhere that this context has to be created in points and there is a mention that on a CGPDFContext one point = 1/72 inches, meaning that the context will have 72 dpi (?).
So, what size should I create this context to have maximum quality at 300 dpi.
Another question is this: supposing this context is created based on the 1/72 stuff, than 7 x 10 inches will represent 504 x 720 pt. If this is the size I have to create the context, what happens when I write the image to the context using this?
CGImageRef imageRef = image.CGImage; // this image is 2100x3000 pixels
// mediaBox = 0,0,504,720
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, &mediaBox, auxillaryInformation);
CGContextDrawImage(pdfContext, CGRectMake(0.0f, 0.0f, 504, 720), imageRef);
will the 2100×3000 pixels image be embedded on the context without losing pixels? I don’t want the image to be reduced to 504×720
3
Answers
The resolution is independent of the media size, in PDF. The media size is given in 1/72 inch, so 2100×3000 ‘units’ (aka points) is a media size of 29.166×41.666 inches. PDF files do not have a resolution.
In general the content of a PDF is vector information and so is resolution independent. Bitmaps may be drawn in a PDF, and those do have a resolution, but its not 72 dpi. The resolution of the image depends on the number of image samples in each dimension, and the scale factor which is applied to put it on the medium.
Consider an image which is 300×300 image samples. If we place that onto a PDF which is 72×72 (ie 1 inch square), and scale it to fit exactly, then the image is, effectively, 300 dpi internally.
In PDF terms I can take the same image, make a PDF page which is 144×144 (2×2 inches), and scale the image to fit that. Now the image is 150 dpi. The image hasn’t changed, but the scale factor has.
Now the final ‘resolution’ of any images in your PDF file, when rendered, will depend on the number of samples and scale factor (as above) and the resolution you render the PDF file at. Taking the 2 cases above, if I render at 300 dpi, the image won’t change at all, but in the first case will map 1:1 the original image samples onto the final output pixels. The second image, however, will map each image sample into 4 pixels in the output (because its been scaled by 2 in each direction).
If you render your PDF file (2100×3100 points) in Photoshop @300 dpi then Photoshop will create a bitmap which is 8750×12500 pixels. It will still be 29.16×41.66 inches, at 300 dots per inch. If you render it at 600 dpi, then you will get 17500×25000 pixels, and so on.
It sounds like the context is created in the default PDF space of 1/72 inch, so you just need to use the media size from the PDF file, ie 2100×3100.
If your image is 2100*3000 pixels and you draw it on a PDF page that is 7*10 inches (504*720 points) then your image will be embedded at 300 dpi.
The image size will be kept at 2100*3000 pixels and it will not be downscaled at 504*720 pixels.
Both other answers are technically correct, but let me try to answer explicitly on both of your questions:
The parameter you have to pass is the location and size of the mediabox of the PDF you want to create. The mediabox is the canvas you have at your disposal to put stuff on.
PDF uses a space where 1 point equals 1/72 inch, but you shouldn’t think of this as dpi in the traditional “image” way. This is simply a convention so that you know that specifying a mediabox with a size of 72 x 72 points will give you a PDF file that is 1 inch high and wide in the real world.
Your code is correct 🙂
The image you place on this context will always be inserted as full size (meaning, Apple will not throw away pixels behind your back). That means that the final resolution of your image is determined by the number of pixels of your image and the size of the rectangle (again in points) where you chose to put it on the page.
So you’re fine in this simple example. However (at the risk of hurting your brain), keep in mind that PDF contexts – just as any other contexts – allow you to transform them. You could rotate or shear the current transformation matrix of your PDF context. In that case your image would still have all pixels, but it’s effective resolution would be dependent on what evil thing you did to the transformation matrix.