Skip to content

Commit

Permalink
Improved SVG image handling
Browse files Browse the repository at this point in the history
  • Loading branch information
endroid committed Apr 26, 2021
1 parent 9ed4de3 commit 35141df
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 24 deletions.
40 changes: 21 additions & 19 deletions src/ImageData/LogoImageData.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,37 +52,39 @@ public static function createForLogo(LogoInterface $logo): self
$mimeType = self::detectMimeTypeFromPath($logo->getPath());
}

$width = $logo->getResizeToWidth();
$height = $logo->getResizeToHeight();

if ('image/svg+xml' === $mimeType) {
if (null === $width || null === $height) {
throw new \Exception('SVG Logos require an explicitly set resize width and height');
}

return new self($data, null, $mimeType, $width, $height);
}

$image = imagecreatefromstring($data);

if (!$image) {
throw new \Exception(sprintf('Unable to parse image data at path "%s"', $logo->getPath()));
}

$width = imagesx($image);
$height = imagesy($image);

$resizeToWidth = $logo->getResizeToWidth();
$resizeToHeight = $logo->getResizeToHeight();

// Fixed resize width and height
if (is_int($resizeToWidth) && is_int($resizeToHeight)) {
$width = $resizeToWidth;
$height = $resizeToHeight;
// No target width and height specified: use from original image
if (null !== $width && null !== $height) {
return new self($data, $image, $mimeType, $width, $height);
}

// Only fixed width: calculate height
if (is_int($resizeToWidth) && is_null($resizeToHeight)) {
$width = $resizeToWidth;
$height = intval(imagesy($image) * $resizeToWidth / imagesx($image));
// Only target width specified: calculate height
if (null !== $width && null === $height) {
return new self($data, $image, $mimeType, $width, intval(imagesy($image) * $width / imagesx($image)));
}

// Only fixed height: calculate width
if (is_int($resizeToHeight) && is_null($resizeToWidth)) {
$height = $resizeToHeight;
$width = intval(imagesx($image) * $resizeToHeight / imagesy($image));
// Only target height specified: calculate width
if (null === $width && null !== $height) {
return new self($data, $image, $mimeType, intval(imagesx($image) * $height / imagesy($image)), $height);
}

return new self($data, $image, $mimeType, $width, $height);
return new self($data, $image, $mimeType, imagesx($image), imagesy($image));
}

public function getData(): string
Expand Down
4 changes: 4 additions & 0 deletions src/Writer/PngWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ private function addLogo(LogoInterface $logo, PngResult $result): PngResult
{
$logoImageData = LogoImageData::createForLogo($logo);

if ('image/svg+xml' === $logoImageData->getMimeType()) {
throw new \Exception('PNG Writer does not support SVG logo');
}

$targetImage = $result->getImage();

imagecopyresampled(
Expand Down
4 changes: 0 additions & 4 deletions src/Writer/SvgWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ private function addLogo(LogoInterface $logo, SvgResult $result, array $options)
$options[self::WRITER_OPTION_FORCE_XLINK_HREF] = false;
}

if ('image/svg+xml' === $logoImageData->getMimeType() && (null === $logo->getResizeToHeight() || null === $logo->getResizeToWidth())) {
throw new \Exception('SVG Logos require an explicit height set via setLogoSize($width, $height)');
}

$xml = $result->getXml();

/** @var \SimpleXMLElement $xmlAttributes */
Expand Down
22 changes: 21 additions & 1 deletion tests/QrCodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,26 @@ public function testBlockSizeTooSmall(): void

$matrixFactory = new MatrixFactory();
$this->expectExceptionMessage('Too much data: increase image dimensions or lower error correction level');
$matrix = $matrixFactory->create($qrCode);
$matrixFactory->create($qrCode);
}

/**
* @testdox PNG Writer does not accept SVG logo, while SVG writer does
*/
public function testSvgLogo(): void
{
$qrCode = QrCode::create('QR Code');
$logo = Logo::create(__DIR__.'/assets/symfony.svg')
->setResizeToWidth(100)
->setResizeToHeight(50)
;

$svgWriter = new SvgWriter();
$result = $svgWriter->write($qrCode, $logo);
$this->assertInstanceOf(SvgResult::class, $result);

$pngWriter = new PngWriter();
$this->expectExceptionMessage('PNG Writer does not support SVG logo');
$pngWriter->write($qrCode, $logo);
}
}
7 changes: 7 additions & 0 deletions tests/assets/symfony.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 35141df

Please sign in to comment.