Skip to content

Commit a65c3c3

Browse files
committed
RTF Writer: Ability to write image
1 parent e00b551 commit a65c3c3

File tree

9 files changed

+124
-64
lines changed

9 files changed

+124
-64
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3; new r
2929
- Word2007 Writer: Enable the missing custom document properties writer - @ivanlanin
3030
- Image: Enable "image float left" - @ivanlanin GH-244
3131
- RTF Writer: Ability to write document properties - @ivanlanin
32+
- RTF Writer: Ability to write image - @ivanlanin
3233

3334
### Bugfixes
3435

docs/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Writers
8383
+---------------------------+----------------------+--------+-------+-------+--------+-------+
8484
| | Table ||| |||
8585
+---------------------------+----------------------+--------+-------+-------+--------+-------+
86-
| | Image ||| || |
86+
| | Image ||| || |
8787
+---------------------------+----------------------+--------+-------+-------+--------+-------+
8888
| | Object || | | | |
8989
+---------------------------+----------------------+--------+-------+-------+--------+-------+

docs/src/documentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Below are the supported features for each file formats.
8989
| | Page Break || || | |
9090
| | List || | | | |
9191
| | Table ||| |||
92-
| | Image ||| || |
92+
| | Image ||| || |
9393
| | Object || | | | |
9494
| | Watermark || | | | |
9595
| | Table of Contents || | | | |

src/PhpWord/Element/AbstractContainer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ protected function addElement($elementName)
8383
$mediaContainer = $this->getMediaContainer();
8484
if (in_array($elementName, array('Link', 'Image', 'Object'))) {
8585
if ($elementName == 'Image') {
86+
/** @var \PhpOffice\PhpWord\Element\Image $element Type hint */
8687
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $element);
8788
} else {
8889
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1]);

src/PhpWord/Element/Image.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,65 @@ public function setMediaIndex($value)
279279
$this->mediaIndex = $value;
280280
}
281281

282+
/**
283+
* Get image string data
284+
*
285+
* @param bool $base64
286+
* @return string|null
287+
*/
288+
public function getImageStringData($base64 = false)
289+
{
290+
$source = $this->source;
291+
$actualSource = null;
292+
$imageBinary = null;
293+
$imageData = null;
294+
295+
// Get actual source from archive image or other source
296+
// Return null if not found
297+
if ($this->sourceType == self::SOURCE_ARCHIVE) {
298+
$source = substr($source, 6);
299+
list($zipFilename, $imageFilename) = explode('#', $source);
300+
301+
$zip = new ZipArchive();
302+
if ($zip->open($zipFilename) !== false) {
303+
if ($zip->locateName($imageFilename)) {
304+
$zip->extractTo(sys_get_temp_dir(), $imageFilename);
305+
$actualSource = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $imageFilename;
306+
}
307+
}
308+
$zip->close();
309+
} else {
310+
$actualSource = $source;
311+
}
312+
if ($actualSource === null) {
313+
return null;
314+
}
315+
316+
// Read image binary data and convert to hex
317+
if ($this->sourceType == self::SOURCE_GD) {
318+
$imageResource = call_user_func($this->imageCreateFunc, $actualSource);
319+
ob_start();
320+
call_user_func($this->imageFunc, $imageResource);
321+
$imageBinary = ob_get_contents();
322+
ob_end_clean();
323+
} else {
324+
$fileHandle = fopen($actualSource, 'rb', false);
325+
if ($fileHandle !== false) {
326+
$imageBinary = fread($fileHandle, filesize($actualSource));
327+
fclose($fileHandle);
328+
}
329+
}
330+
if ($imageBinary !== null) {
331+
if ($base64) {
332+
$imageData = chunk_split(base64_encode($imageBinary));
333+
} else {
334+
$imageData = chunk_split(bin2hex($imageBinary));
335+
}
336+
}
337+
338+
return $imageData;
339+
}
340+
282341
/**
283342
* Check memory image, supported type, image functions, and proportional width/height
284343
*

src/PhpWord/Style/Table.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ public function setCellMarginBottom($value = null)
430430
/**
431431
* Get cell margin
432432
*
433-
* @return integer[]
433+
* @return int[]
434434
*/
435435
public function getCellMargin()
436436
{

src/PhpWord/Writer/HTML/Element/Image.php

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
namespace PhpOffice\PhpWord\Writer\HTML\Element;
1919

2020
use PhpOffice\PhpWord\Element\Image as ImageElement;
21-
use PhpOffice\PhpWord\Shared\ZipArchive;
2221
use PhpOffice\PhpWord\Writer\HTML\Style\Image as ImageStyleWriter;
2322

2423
/**
@@ -43,10 +42,11 @@ public function write()
4342

4443
$content = '';
4544
if (!$parentWriter->isPdf()) {
46-
$imageData = $this->getBase64ImageData($this->element);
47-
if (!is_null($imageData)) {
45+
$imageData = $this->element->getImageStringData(true);
46+
if ($imageData !== null) {
4847
$styleWriter = new ImageStyleWriter($this->element->getStyle());
4948
$style = $styleWriter->write();
49+
$imageData = 'data:' . $this->element->getImageType() . ';base64,' . $imageData;
5050

5151
$content .= $this->writeOpening();
5252
$content .= "<img border=\"0\" style=\"{$style}\" src=\"{$imageData}\"/>";
@@ -56,61 +56,4 @@ public function write()
5656

5757
return $content;
5858
}
59-
60-
/**
61-
* Get Base64 image data
62-
*
63-
* @param \PhpOffice\PhpWord\Element\Image $element
64-
* @return string|null
65-
*/
66-
private function getBase64ImageData(ImageElement $element)
67-
{
68-
$source = $element->getSource();
69-
$imageType = $element->getImageType();
70-
$imageData = null;
71-
$imageBinary = null;
72-
$actualSource = null;
73-
74-
// Get actual source from archive image or other source
75-
// Return null if not found
76-
if ($element->getSourceType() == ImageElement::SOURCE_ARCHIVE) {
77-
$source = substr($source, 6);
78-
list($zipFilename, $imageFilename) = explode('#', $source);
79-
80-
$zip = new ZipArchive();
81-
if ($zip->open($zipFilename) !== false) {
82-
if ($zip->locateName($imageFilename)) {
83-
$zip->extractTo($this->parentWriter->getTempDir(), $imageFilename);
84-
$actualSource = $this->parentWriter->getTempDir() . DIRECTORY_SEPARATOR . $imageFilename;
85-
}
86-
}
87-
$zip->close();
88-
} else {
89-
$actualSource = $source;
90-
}
91-
if ($actualSource === null) {
92-
return null;
93-
}
94-
95-
// Read image binary data and convert into Base64
96-
if ($element->getSourceType() == ImageElement::SOURCE_GD) {
97-
$imageResource = call_user_func($element->getImageCreateFunction(), $actualSource);
98-
ob_start();
99-
call_user_func($element->getImageFunction(), $imageResource);
100-
$imageBinary = ob_get_contents();
101-
ob_end_clean();
102-
} else {
103-
$fileHandle = fopen($actualSource, 'rb', false);
104-
if ($fileHandle !== false) {
105-
$imageBinary = fread($fileHandle, filesize($actualSource));
106-
fclose($fileHandle);
107-
}
108-
}
109-
if ($imageBinary !== null) {
110-
$base64 = chunk_split(base64_encode($imageBinary));
111-
$imageData = 'data:' . $imageType . ';base64,' . $base64;
112-
}
113-
114-
return $imageData;
115-
}
11659
}

src/PhpWord/Writer/HTML/Part/Head.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
*/
3333
class Head extends AbstractPart
3434
{
35-
3635
/**
3736
* Write part
3837
*
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* This file is part of PHPWord - A pure PHP library for reading and writing
4+
* word processing documents.
5+
*
6+
* PHPWord is free software distributed under the terms of the GNU Lesser
7+
* General Public License version 3 as published by the Free Software Foundation.
8+
*
9+
* For the full copyright and license information, please read the LICENSE
10+
* file that was distributed with this source code. For the full list of
11+
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
12+
*
13+
* @link https://github.com/PHPOffice/PHPWord
14+
* @copyright 2010-2014 PHPWord contributors
15+
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16+
*/
17+
18+
namespace PhpOffice\PhpWord\Writer\RTF\Element;
19+
20+
use PhpOffice\PhpWord\Element\Image as ImageElement;
21+
use PhpOffice\PhpWord\Shared\Font;
22+
23+
/**
24+
* Image element RTF writer
25+
*
26+
* @since 0.11.0
27+
*/
28+
class Image extends AbstractElement
29+
{
30+
/**
31+
* Write element
32+
*
33+
* @return string
34+
*/
35+
public function write()
36+
{
37+
if (!$this->element instanceof ImageElement) {
38+
return '';
39+
}
40+
41+
$this->getStyles();
42+
$style = $this->element->getStyle();
43+
44+
$content = '';
45+
$content .= $this->writeOpening();
46+
$content .= '{\*\shppict {\pict';
47+
$content .= '\pngblip\picscalex100\picscaley100';
48+
$content .= '\picwgoal' . round(Font::pixelSizeToTwips($style->getWidth()));
49+
$content .= '\pichgoal' . round(Font::pixelSizeToTwips($style->getHeight()));
50+
$content .= PHP_EOL;
51+
$content .= $this->element->getImageStringData();
52+
$content .= '}}';
53+
$content .= $this->writeClosing();
54+
55+
return $content;
56+
}
57+
}

0 commit comments

Comments
 (0)