Skip to content

Commit

Permalink
Merge pull request #937 from troosan/image_from_string
Browse files Browse the repository at this point in the history
add support for Image creation from string image data
  • Loading branch information
Progi1984 committed Dec 13, 2016
2 parents 60e7f53 + 204f0c3 commit c4c35dd
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/elements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ To add an image, use the ``addImage`` method to sections, headers, footers, text
$section->addImage($src, [$style]);
- ``$src``. String path to a local image or URL of a remote image.
- ``$src``. String path to a local image, URL of a remote image or the image data, as a string.
- ``$style``. See :ref:`image-style`.

Examples:
Expand All @@ -254,6 +254,8 @@ Examples:
$footer->addImage('http://example.com/image.php');
$textrun = $section->addTextRun();
$textrun->addImage('http://php.net/logo.jpg');
$source = file_get_contents('/path/to/my/images/earth.jpg');
$textrun->addImage($source);
Watermarks
~~~~~~~~~~
Expand Down
31 changes: 29 additions & 2 deletions src/PhpWord/Element/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Image extends AbstractElement
const SOURCE_LOCAL = 'local'; // Local images
const SOURCE_GD = 'gd'; // Generated using GD
const SOURCE_ARCHIVE = 'archive'; // Image in archives zip://$archive#$image
const SOURCE_STRING = 'string'; // Image from string

/**
* Image source
Expand Down Expand Up @@ -379,6 +380,8 @@ private function checkImage($source)
// Check image data
if ($this->sourceType == self::SOURCE_ARCHIVE) {
$imageData = $this->getArchiveImageSize($source);
} else if ($this->sourceType == self::SOURCE_STRING) {
$imageData = $this->getStringImageSize($source);
} else {
$imageData = @getimagesize($source);
}
Expand Down Expand Up @@ -416,9 +419,15 @@ private function setSourceType($source)
} elseif (strpos($source, 'zip://') !== false) {
$this->memoryImage = false;
$this->sourceType = self::SOURCE_ARCHIVE;
} elseif (filter_var($source, FILTER_VALIDATE_URL) !== false) {
$this->memoryImage = true;
$this->sourceType = self::SOURCE_GD;
} elseif (@file_exists($source)) {
$this->memoryImage = false;
$this->sourceType = self::SOURCE_LOCAL;
} else {
$this->memoryImage = (filter_var($source, FILTER_VALIDATE_URL) !== false);
$this->sourceType = $this->memoryImage ? self::SOURCE_GD : self::SOURCE_LOCAL;
$this->memoryImage = true;
$this->sourceType = self::SOURCE_STRING;
}
}

Expand Down Expand Up @@ -460,6 +469,24 @@ private function getArchiveImageSize($source)
return $imageData;
}

/**
* get image size from string
*
* @param string $source
*
* @codeCoverageIgnore this method is just a replacement for getimagesizefromstring which exists only as of PHP 5.4
*/
private function getStringImageSize($source)
{
if (!function_exists('getimagesizefromstring')) {
$uri = 'data://application/octet-stream;base64,' . base64_encode($source);
return @getimagesize($uri);
} else {
return @getimagesizefromstring($source);
}
return false;
}

/**
* Set image functions and extensions.
*
Expand Down
53 changes: 53 additions & 0 deletions tests/PhpWord/Element/ImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,57 @@ public function testArchivedImage()
$image = new Image("zip://{$archiveFile}#{$imageFile}");
$this->assertEquals('image/jpeg', $image->getImageType());
}

/**
* Test getting image as string
*/
public function testImageAsStringFromFile()
{
$image = new Image(__DIR__ . '/../_files/images/earth.jpg');

$this->assertNotNull($image->getImageStringData());
$this->assertNotNull($image->getImageStringData(true));
}

/**
* Test getting image from zip as string
*/
public function testImageAsStringFromZip()
{
$archiveFile = __DIR__ . '/../_files/documents/reader.docx';
$imageFile = 'word/media/image1.jpeg';
$image = new Image("zip://{$archiveFile}#{$imageFile}");

$this->assertNotNull($image->getImageStringData());
$this->assertNotNull($image->getImageStringData(true));
}

/**
* Test construct from string
*/
public function testConstructFromString()
{
$source = file_get_contents(__DIR__ . '/../_files/images/earth.jpg');

$image = new Image($source);
$this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $image);
$this->assertEquals($source, $image->getSource());
$this->assertEquals(md5($source), $image->getMediaId());
$this->assertEquals('image/jpeg', $image->getImageType());
$this->assertEquals('jpg', $image->getImageExtension());
$this->assertEquals('imagecreatefromjpeg', $image->getImageCreateFunction());
$this->assertEquals('imagejpeg', $image->getImageFunction());
$this->assertTrue($image->isMemImage());
}

/**
* Test invalid string image
*
* @expectedException \PhpOffice\PhpWord\Exception\InvalidImageException
*/
public function testInvalidImageString()
{
$object = new Image('this_is-a_non_valid_image');
$object->getSource();
}
}

0 comments on commit c4c35dd

Please sign in to comment.