From a65c3c3cf1d2628502fbf5f766405466f2b20f68 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 23 May 2014 18:32:56 +0700 Subject: [PATCH] RTF Writer: Ability to write image --- CHANGELOG.md | 1 + docs/intro.rst | 2 +- docs/src/documentation.md | 2 +- src/PhpWord/Element/AbstractContainer.php | 1 + src/PhpWord/Element/Image.php | 59 +++++++++++++++++++++ src/PhpWord/Style/Table.php | 2 +- src/PhpWord/Writer/HTML/Element/Image.php | 63 ++--------------------- src/PhpWord/Writer/HTML/Part/Head.php | 1 - src/PhpWord/Writer/RTF/Element/Image.php | 57 ++++++++++++++++++++ 9 files changed, 124 insertions(+), 64 deletions(-) create mode 100644 src/PhpWord/Writer/RTF/Element/Image.php diff --git a/CHANGELOG.md b/CHANGELOG.md index daaddb60..68ea9d2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3; new r - Word2007 Writer: Enable the missing custom document properties writer - @ivanlanin - Image: Enable "image float left" - @ivanlanin GH-244 - RTF Writer: Ability to write document properties - @ivanlanin +- RTF Writer: Ability to write image - @ivanlanin ### Bugfixes diff --git a/docs/intro.rst b/docs/intro.rst index 55a0764c..a64fb2ad 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -83,7 +83,7 @@ Writers +---------------------------+----------------------+--------+-------+-------+--------+-------+ | | Table | ✓ | ✓ | | ✓ | ✓ | +---------------------------+----------------------+--------+-------+-------+--------+-------+ -| | Image | ✓ | ✓ | | ✓ | | +| | Image | ✓ | ✓ | ✓ | ✓ | | +---------------------------+----------------------+--------+-------+-------+--------+-------+ | | Object | ✓ | | | | | +---------------------------+----------------------+--------+-------+-------+--------+-------+ diff --git a/docs/src/documentation.md b/docs/src/documentation.md index dce1f5db..abb8777e 100644 --- a/docs/src/documentation.md +++ b/docs/src/documentation.md @@ -89,7 +89,7 @@ Below are the supported features for each file formats. | | Page Break | ✓ | | ✓ | | | | | List | ✓ | | | | | | | Table | ✓ | ✓ | | ✓ | ✓ | -| | Image | ✓ | ✓ | | ✓ | | +| | Image | ✓ | ✓ | ✓ | ✓ | | | | Object | ✓ | | | | | | | Watermark | ✓ | | | | | | | Table of Contents | ✓ | | | | | diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index f469686d..06a94489 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -83,6 +83,7 @@ abstract class AbstractContainer extends AbstractElement $mediaContainer = $this->getMediaContainer(); if (in_array($elementName, array('Link', 'Image', 'Object'))) { if ($elementName == 'Image') { + /** @var \PhpOffice\PhpWord\Element\Image $element Type hint */ $rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $element); } else { $rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1]); diff --git a/src/PhpWord/Element/Image.php b/src/PhpWord/Element/Image.php index 8e30b78c..c38fda2c 100644 --- a/src/PhpWord/Element/Image.php +++ b/src/PhpWord/Element/Image.php @@ -279,6 +279,65 @@ class Image extends AbstractElement $this->mediaIndex = $value; } + /** + * Get image string data + * + * @param bool $base64 + * @return string|null + */ + public function getImageStringData($base64 = false) + { + $source = $this->source; + $actualSource = null; + $imageBinary = null; + $imageData = null; + + // Get actual source from archive image or other source + // Return null if not found + if ($this->sourceType == self::SOURCE_ARCHIVE) { + $source = substr($source, 6); + list($zipFilename, $imageFilename) = explode('#', $source); + + $zip = new ZipArchive(); + if ($zip->open($zipFilename) !== false) { + if ($zip->locateName($imageFilename)) { + $zip->extractTo(sys_get_temp_dir(), $imageFilename); + $actualSource = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $imageFilename; + } + } + $zip->close(); + } else { + $actualSource = $source; + } + if ($actualSource === null) { + return null; + } + + // Read image binary data and convert to hex + if ($this->sourceType == self::SOURCE_GD) { + $imageResource = call_user_func($this->imageCreateFunc, $actualSource); + ob_start(); + call_user_func($this->imageFunc, $imageResource); + $imageBinary = ob_get_contents(); + ob_end_clean(); + } else { + $fileHandle = fopen($actualSource, 'rb', false); + if ($fileHandle !== false) { + $imageBinary = fread($fileHandle, filesize($actualSource)); + fclose($fileHandle); + } + } + if ($imageBinary !== null) { + if ($base64) { + $imageData = chunk_split(base64_encode($imageBinary)); + } else { + $imageData = chunk_split(bin2hex($imageBinary)); + } + } + + return $imageData; + } + /** * Check memory image, supported type, image functions, and proportional width/height * diff --git a/src/PhpWord/Style/Table.php b/src/PhpWord/Style/Table.php index 68b53463..90e8282f 100644 --- a/src/PhpWord/Style/Table.php +++ b/src/PhpWord/Style/Table.php @@ -430,7 +430,7 @@ class Table extends Border /** * Get cell margin * - * @return integer[] + * @return int[] */ public function getCellMargin() { diff --git a/src/PhpWord/Writer/HTML/Element/Image.php b/src/PhpWord/Writer/HTML/Element/Image.php index 698b7e86..ab78990b 100644 --- a/src/PhpWord/Writer/HTML/Element/Image.php +++ b/src/PhpWord/Writer/HTML/Element/Image.php @@ -18,7 +18,6 @@ namespace PhpOffice\PhpWord\Writer\HTML\Element; use PhpOffice\PhpWord\Element\Image as ImageElement; -use PhpOffice\PhpWord\Shared\ZipArchive; use PhpOffice\PhpWord\Writer\HTML\Style\Image as ImageStyleWriter; /** @@ -43,10 +42,11 @@ class Image extends Text $content = ''; if (!$parentWriter->isPdf()) { - $imageData = $this->getBase64ImageData($this->element); - if (!is_null($imageData)) { + $imageData = $this->element->getImageStringData(true); + if ($imageData !== null) { $styleWriter = new ImageStyleWriter($this->element->getStyle()); $style = $styleWriter->write(); + $imageData = 'data:' . $this->element->getImageType() . ';base64,' . $imageData; $content .= $this->writeOpening(); $content .= ""; @@ -56,61 +56,4 @@ class Image extends Text return $content; } - - /** - * Get Base64 image data - * - * @param \PhpOffice\PhpWord\Element\Image $element - * @return string|null - */ - private function getBase64ImageData(ImageElement $element) - { - $source = $element->getSource(); - $imageType = $element->getImageType(); - $imageData = null; - $imageBinary = null; - $actualSource = null; - - // Get actual source from archive image or other source - // Return null if not found - if ($element->getSourceType() == ImageElement::SOURCE_ARCHIVE) { - $source = substr($source, 6); - list($zipFilename, $imageFilename) = explode('#', $source); - - $zip = new ZipArchive(); - if ($zip->open($zipFilename) !== false) { - if ($zip->locateName($imageFilename)) { - $zip->extractTo($this->parentWriter->getTempDir(), $imageFilename); - $actualSource = $this->parentWriter->getTempDir() . DIRECTORY_SEPARATOR . $imageFilename; - } - } - $zip->close(); - } else { - $actualSource = $source; - } - if ($actualSource === null) { - return null; - } - - // Read image binary data and convert into Base64 - if ($element->getSourceType() == ImageElement::SOURCE_GD) { - $imageResource = call_user_func($element->getImageCreateFunction(), $actualSource); - ob_start(); - call_user_func($element->getImageFunction(), $imageResource); - $imageBinary = ob_get_contents(); - ob_end_clean(); - } else { - $fileHandle = fopen($actualSource, 'rb', false); - if ($fileHandle !== false) { - $imageBinary = fread($fileHandle, filesize($actualSource)); - fclose($fileHandle); - } - } - if ($imageBinary !== null) { - $base64 = chunk_split(base64_encode($imageBinary)); - $imageData = 'data:' . $imageType . ';base64,' . $base64; - } - - return $imageData; - } } diff --git a/src/PhpWord/Writer/HTML/Part/Head.php b/src/PhpWord/Writer/HTML/Part/Head.php index 389d568b..edbc8dcf 100644 --- a/src/PhpWord/Writer/HTML/Part/Head.php +++ b/src/PhpWord/Writer/HTML/Part/Head.php @@ -32,7 +32,6 @@ use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter; */ class Head extends AbstractPart { - /** * Write part * diff --git a/src/PhpWord/Writer/RTF/Element/Image.php b/src/PhpWord/Writer/RTF/Element/Image.php new file mode 100644 index 00000000..1daae2a0 --- /dev/null +++ b/src/PhpWord/Writer/RTF/Element/Image.php @@ -0,0 +1,57 @@ +element instanceof ImageElement) { + return ''; + } + + $this->getStyles(); + $style = $this->element->getStyle(); + + $content = ''; + $content .= $this->writeOpening(); + $content .= '{\*\shppict {\pict'; + $content .= '\pngblip\picscalex100\picscaley100'; + $content .= '\picwgoal' . round(Font::pixelSizeToTwips($style->getWidth())); + $content .= '\pichgoal' . round(Font::pixelSizeToTwips($style->getHeight())); + $content .= PHP_EOL; + $content .= $this->element->getImageStringData(); + $content .= '}}'; + $content .= $this->writeClosing(); + + return $content; + } +}