Skip to content

Commit

Permalink
Add support for inline SVG's
Browse files Browse the repository at this point in the history
  • Loading branch information
casperbakker committed Mar 31, 2024
1 parent 1c4bc99 commit 9aba4bc
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 137 deletions.
50 changes: 40 additions & 10 deletions src/BarcodeGeneratorJPG.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,51 @@

namespace Picqer\Barcode;

use Imagick;

class BarcodeGeneratorJPG extends BarcodeGeneratorPNG
class BarcodeGeneratorJPG extends BarcodeGenerator
{
protected function createImagickImageObject(int $width, int $height): Imagick
protected ?bool $useImagick = null;

/**
* Return a PNG image representation of barcode (requires GD or Imagick library).
*
* @param string $barcode code to print
* @param BarcodeGenerator::TYPE_* $type (string) type of barcode
* @param int $widthFactor Width of a single bar element in pixels.
* @param int $height Height of a single bar element in pixels.
* @param array $foregroundColor RGB (0-255) foreground color for bar elements (background is transparent).
* @return string image data or false in case of error.
*/
public function getBarcode(string $barcode, $type, int $widthFactor = 2, int $height = 30, array $foregroundColor = [0, 0, 0]): string
{
$image = new Imagick();
$image->newImage($width, $height, 'white', 'JPG');
$barcodeData = $this->getBarcodeData($barcode, $type);

$renderer = new \Picqer\Barcode\Renderers\JpgRenderer();
$renderer->setForegroundColor($foregroundColor);

if (! is_null($this->useImagick)) {
if ($this->useImagick) {
$renderer->useImagick();
} else {
$renderer->useGd();
}
}

return $image;
return $renderer->render($barcodeData, $widthFactor, $height);
}

/**
* Force the use of Imagick image extension
*/
public function useImagick()
{
$this->useImagick = true;
}

protected function generateGdImage($image)
/**
* Force the use of the GD image library
*/
public function useGd()
{
imagejpeg($image);
imagedestroy($image);
$this->useImagick = false;
}
}
107 changes: 19 additions & 88 deletions src/BarcodeGeneratorPNG.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,9 @@

namespace Picqer\Barcode;

use Imagick;
use imagickdraw;
use imagickpixel;
use Picqer\Barcode\Exceptions\BarcodeException;

class BarcodeGeneratorPNG extends BarcodeGenerator
{
protected $useImagick = true;

/**
* @throws BarcodeException
*/
public function __construct()
{
// Auto switch between GD and Imagick based on what is installed
if (extension_loaded('imagick')) {
$this->useImagick = true;
} elseif (function_exists('imagecreate')) {
$this->useImagick = false;
} else {
throw new BarcodeException('Neither gd-lib or imagick are installed!');
}
}

/**
* Force the use of Imagick image extension
*/
public function useImagick()
{
$this->useImagick = true;
}

/**
* Force the use of the GD image library
*/
public function useGd()
{
$this->useImagick = false;
}
protected ?bool $useImagick = null;

/**
* Return a PNG image representation of barcode (requires GD or Imagick library).
Expand All @@ -55,67 +19,34 @@ public function useGd()
public function getBarcode(string $barcode, $type, int $widthFactor = 2, int $height = 30, array $foregroundColor = [0, 0, 0]): string
{
$barcodeData = $this->getBarcodeData($barcode, $type);
$width = round($barcodeData->getWidth() * $widthFactor);

if ($this->useImagick) {
$imagickBarsShape = new imagickdraw();
$imagickBarsShape->setFillColor(new imagickpixel('rgb(' . implode(',', $foregroundColor) .')'));
} else {
$image = $this->createGdImageObject($width, $height);
$gdForegroundColor = imagecolorallocate($image, $foregroundColor[0], $foregroundColor[1], $foregroundColor[2]);
}

// print bars
$positionHorizontal = 0;
/** @var BarcodeBar $bar */
foreach ($barcodeData->getBars() as $bar) {
$barWidth = round(($bar->getWidth() * $widthFactor), 3);
$renderer = new \Picqer\Barcode\Renderers\PngRenderer();
$renderer->setForegroundColor($foregroundColor);

if ($bar->isBar() && $barWidth > 0) {
$y = round(($bar->getPositionVertical() * $height / $barcodeData->getHeight()), 3);
$barHeight = round(($bar->getHeight() * $height / $barcodeData->getHeight()), 3);

// draw a vertical bar
if ($this->useImagick) {
$imagickBarsShape->rectangle($positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight));
} else {
imagefilledrectangle($image, $positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight), $gdForegroundColor);
}
if (! is_null($this->useImagick)) {
if ($this->useImagick) {
$renderer->useImagick();
} else {
$renderer->useGd();
}
$positionHorizontal += $barWidth;
}

if ($this->useImagick) {
$image = $this->createImagickImageObject($width, $height);
$image->drawImage($imagickBarsShape);
return $image->getImageBlob();
}

ob_start();
$this->generateGdImage($image);
return ob_get_clean();
return $renderer->render($barcodeData, $widthFactor, $height);
}

protected function createGdImageObject(int $width, int $height)
{
$image = imagecreate($width, $height);
$colorBackground = imagecolorallocate($image, 255, 255, 255);
imagecolortransparent($image, $colorBackground);

return $image;
}

protected function createImagickImageObject(int $width, int $height): Imagick
/**
* Force the use of Imagick image extension
*/
public function useImagick()
{
$image = new Imagick();
$image->newImage($width, $height, 'none', 'PNG');

return $image;
$this->useImagick = true;
}

protected function generateGdImage($image)
/**
* Force the use of the GD image library
*/
public function useGd()
{
imagepng($image);
imagedestroy($image);
$this->useImagick = false;
}
}
5 changes: 5 additions & 0 deletions src/Exceptions/InvalidOptionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Picqer\Barcode\Exceptions;

class InvalidOptionException extends BarcodeException {}
22 changes: 22 additions & 0 deletions src/Renderers/JpgRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Picqer\Barcode\Renderers;

use Imagick;

class JpgRenderer extends PngRenderer
{
protected function createImagickImageObject(int $width, int $height): Imagick
{
$image = new Imagick();
$image->newImage($width, $height, 'none', 'JPG');

return $image;
}

protected function generateGdImage($image)
{
\imagejpeg($image);
\imagedestroy($image);
}
}
118 changes: 118 additions & 0 deletions src/Renderers/PngRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

namespace Picqer\Barcode\Renderers;

use Imagick;
use ImagickDraw;
use ImagickPixel;
use Picqer\Barcode\Barcode;
use Picqer\Barcode\BarcodeBar;
use Picqer\Barcode\Exceptions\BarcodeException;

class PngRenderer
{
protected array $foregroundColor = [0, 0, 0];
protected bool $useImagick;

/**
* @throws BarcodeException
*/
public function __construct()
{
// Auto switch between GD and Imagick based on what is installed
if (extension_loaded('imagick')) {
$this->useImagick = true;
} elseif (function_exists('imagecreate')) {
$this->useImagick = false;
} else {
throw new BarcodeException('Neither gd-lib or imagick are installed!');
}
}

/**
* Force the use of Imagick image extension
*/
public function useImagick()
{
$this->useImagick = true;
}

/**
* Force the use of the GD image library
*/
public function useGd()
{
$this->useImagick = false;
}

public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30): string
{
$width = round($barcode->getWidth() * $widthFactor);

if ($this->useImagick) {
$imagickBarsShape = new ImagickDraw();
$imagickBarsShape->setFillColor(new ImagickPixel('rgb(' . implode(',', $this->foregroundColor) .')'));
} else {
$image = $this->createGdImageObject($width, $height);
$gdForegroundColor = \imagecolorallocate($image, $this->foregroundColor[0], $this->foregroundColor[1], $this->foregroundColor[2]);
}

// print bars
$positionHorizontal = 0;
/** @var BarcodeBar $bar */
foreach ($barcode->getBars() as $bar) {
$barWidth = round(($bar->getWidth() * $widthFactor), 3);

if ($bar->isBar() && $barWidth > 0) {
$y = round(($bar->getPositionVertical() * $height / $barcode->getHeight()), 3);
$barHeight = round(($bar->getHeight() * $height / $barcode->getHeight()), 3);

// draw a vertical bar
if ($this->useImagick) {
$imagickBarsShape->rectangle($positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight));
} else {
\imagefilledrectangle($image, $positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight), $gdForegroundColor);
}
}
$positionHorizontal += $barWidth;
}

if ($this->useImagick) {
$image = $this->createImagickImageObject($width, $height);
$image->drawImage($imagickBarsShape);
return $image->getImageBlob();
}

ob_start();
$this->generateGdImage($image);
return ob_get_clean();
}

public function setForegroundColor(array $color)
{
$this->foregroundColor = $color;
}

protected function createGdImageObject(int $width, int $height)
{
$image = \imagecreate($width, $height);
$colorBackground = \imagecolorallocate($image, 255, 255, 255);
\imagecolortransparent($image, $colorBackground);

return $image;
}

protected function createImagickImageObject(int $width, int $height): Imagick
{
$image = new Imagick();
$image->newImage($width, $height, 'none', 'PNG');

return $image;
}

protected function generateGdImage($image)
{
\imagepng($image);
\imagedestroy($image);
}
}
Loading

0 comments on commit 9aba4bc

Please sign in to comment.