PDFs with PHP part 2 - File Checking (Page 7 of 8 )
To keep this example simple the file checking is rather crude. We guess the image type according to what its extension is. Ideally we should be using a better way to check the image type, regardless of extension.
The _parseJPG() method does a further check to make sure we are dealing with a JPEG file.
We will need to add a few other functions to handle the inserting of images. First of all there is the _parseJPG() method we saw in the function above:
function _parseJPG
($file)
{
/* Extract info from the JPEG file. */
$img = @getimagesize($file);
if (!$img) {
die(sprintf('Missing or incorrect image file: %s', $file));
}
/* Check if dealing with an actual JPEG. */
if ($img[2] != 2) {
die(sprintf('Not a JPEG file: %s', $file));
}
/* Get the image colorspace. */
if (!isset($img['channels']) || $img['channels'] == 3) {
$colspace = 'DeviceRGB';
} elseif ($img['channels'] == 4) {
$colspace = 'DeviceCMYK';
} else {
$colspace = 'DeviceGray';
}
$bpc = isset($img['bits']) ? $img['bits'] : 8;
/* Read the whole file. */
$f = fopen($file, 'rb');
$data = fread($f, filesize($file));
fclose($f);
return array('w' => $img[0], 'h' => $img[1], 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data);
}
All that this function does is to check that the file format is JPEG, get the colorspace, and read the file data. It returns an array containing width, height, colorspace, bits, filter (always 'DCTDecode' for JPEG), and the actual data.
Our _putResources() function that we set up in Part 1 of this tutorial, now needs to add images as well. This is how the modified function should look. Note the added call to _putImages(), the extra parameters in the 'ProcSet' line, and the loop to output the image objects.
function _putResources
()
{
$this->_putFonts(); // Output any fonts.
$this->_putImages(); // Output any images.
/* Resources are always object number 2. */
$this->_offsets[2] = strlen($this->_buffer);
$this->_out('2 0 obj');
$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
$this->_out('/Font <<');
foreach ($this->_fonts as $font) {
$this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R');
}
$this->_out('>>');
if (count($this->_images)) { // Loop through any images
$this->_out('/XObject <<'); // and output the objects.
foreach ($this->_images as $image) {
$this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R');
}
$this->_out('>>');
}
$this->_out('>>');
$this->_out('endobj');
}
The above function calls the _putImages() to output the actual image data:
function _putImages
()
{
/* Output any images. */
$filter = ($this->_compress) ? '/Filter /FlateDe ' : '';
foreach ($this->_images as $file => $info) {
$this->_newobj();
$this->_images[$file]['n'] = $this->_n;
$this->_out('<</Type /XObject');
$this->_out('/Subtype /Image');
$this->_out('/Width ' . $info['w']); // Image width.
$this->_out('/Height ' . $info['h']); // Image height.
$this->_out('/ColorSpace /' . $info['cs']); //Colorspace
if ($info['cs'] == 'DeviceCMYK') {
$this->_out('/De [1 0 1 0 1 0 1 0]');
}
$this->_out('/BitsPerComponent ' . $info['bpc']); // Bits
$this->_out('/Filter /' . $info['f']); // Filter used.
$this->_out('/Length ' . strlen($info['data']) . '>>');
$this->_putStream($info['data']); // Image data.
$this->_out('endobj');
}
}
The Script
You can download the
entire class for use with Part 2 of this tutorial.
Next: Example Use >>
More Zend Articles
More By Zend