Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for background colors #205

Merged
merged 3 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ Each renderer has their own options. Only the barcode is required, the rest is o
A vector based SVG image. Gives the best quality to print.
```php
$renderer = new Picqer\Barcode\Renderers\SvgRenderer();
$renderer->setForegroundColor('red'); // Give a color for the bars, the background is always white
$renderer->setForegroundColor('red'); // Give a color for the bars, default is black
$renderer->setBackgroundColor('blue'); // Give a color for the background, default is transparent
$renderer->setSvgType($renderer::TYPE_SVG_INLINE); // Changes the output to be used inline inside HTML documents, instead of a standalone SVG image (default)
$renderer->setSvgType($renderer::TYPE_SVG_STANDALONE); // If you want to force the default, create a stand alone SVG image

Expand All @@ -78,7 +79,8 @@ $renderer->render($barcode, 450.20, 75); // Width and height support floats
All options for PNG and JPG are the same.
```php
$renderer = new Picqer\Barcode\Renderers\PngRenderer();
$renderer->setForegroundColor([255, 0, 0]); // Give a color for the bars, the background is always white. Give it as 3 times 0-255 values for red, green and blue.
$renderer->setForegroundColor([255, 0, 0]); // Give a color for the bars, default is black. Give it as 3 times 0-255 values for red, green and blue.
$renderer->setBackgroundColor([0, 255, 255]); // Give a color for the background, default is transparent (in PNG) or white (in JPG). Give it as 3 times 0-255 values for red, green and blue.
$renderer->useGd(); // If you have Imagick and GD installed, but want to use GD
$renderer->useImagick(); // If you have Imagick and GD installed, but want to use Imagick

Expand All @@ -89,7 +91,8 @@ $renderer->render($barcode, 5, 40); // Width factor (how many pixel wide every b
Gives HTML to use inline in a full HTML document.
```php
$renderer = new Picqer\Barcode\Renderers\HtmlRenderer();
$renderer->setForegroundColor('red'); // Give a color for the bars, the background is always white
$renderer->setForegroundColor('red'); // Give a color for the bars, default is black
$renderer->setBackgroundColor('blue'); // Give a color for the background, default is transparent

$renderer->render($barcode, 450.20, 75); // Width and height support floats
````
Expand All @@ -98,7 +101,8 @@ $renderer->render($barcode, 450.20, 75); // Width and height support floats
Give HTML here the barcode is using the full width and height, to put inside a container/div that has a fixed size.
```php
$renderer = new Picqer\Barcode\Renderers\DynamicHtmlRenderer();
$renderer->setForegroundColor('red'); // Give a color for the bars, the background is always white
$renderer->setForegroundColor('red'); // Give a color for the bars, default is black
$renderer->setBackgroundColor('blue'); // Give a color for the background, default is transparent

$renderer->render($barcode);
````
Expand Down
7 changes: 7 additions & 0 deletions generate-verified-files.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@
file_put_contents('tests/verified-files/081231723897-ean13.svg', $svgRenderer->render($barcode, $barcode->getWidth() * 2));
file_put_contents('tests/verified-files/081231723897-ean13-fractional-width.svg', $svgRenderer->render($barcode, $barcode->getWidth() * 0.25, 25.75));

$svgRendererRed = new Picqer\Barcode\Renderers\SvgRenderer();
$svgRendererRed->setBackgroundColor('red');
file_put_contents('tests/verified-files/081231723897-ean13-red-background.svg', $svgRendererRed->render($barcode, $barcode->getWidth() * 2));

$barcode = $typeEncoderCode128->getBarcode('081231723897');
file_put_contents('tests/verified-files/081231723897-code128.html', $htmlRenderer->render($barcode, $barcode->getWidth() * 2));
$htmlRendererRed = new Picqer\Barcode\Renderers\HtmlRenderer();
$htmlRendererRed->setBackgroundColor('red');
file_put_contents('tests/verified-files/081231723897-code128-red-background.html', $htmlRendererRed->render($barcode, $barcode->getWidth() * 2));

$barcode = $typeEncoderIMB->getBarcode('12345678903');
file_put_contents('tests/verified-files/12345678903-imb.html', $htmlRenderer->render($barcode, $barcode->getWidth() * 2));
Expand Down
10 changes: 9 additions & 1 deletion src/Renderers/DynamicHtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ class DynamicHtmlRenderer
protected const WIDTH_PRECISION = 6;

protected string $foregroundColor = 'black';
protected ?string $backgroundColor = null;

public function render(Barcode $barcode): string
{
$html = '<div style="font-size:0;position:relative;width:100%;height:100%">' . PHP_EOL;
$html = '<div style="font-size:0;position:relative;width:100%;height:100%' . ($this->backgroundColor ? ';background-color:' . $this->backgroundColor : '') . '">' . PHP_EOL;

$positionHorizontal = 0;
/** @var BarcodeBar $bar */
Expand All @@ -36,10 +37,17 @@ public function render(Barcode $barcode): string
return $html;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setForegroundColor(string $color): self
{
$this->foregroundColor = $color;
return $this;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setBackgroundColor(?string $color): self
{
$this->backgroundColor = $color;
return $this;
}
}
12 changes: 10 additions & 2 deletions src/Renderers/HtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
class HtmlRenderer
{
protected string $foregroundColor = 'black';
protected ?string $backgroundColor = null;

public function render(Barcode $barcode, float $width = 200, float $height = 30): string
{
$widthFactor = $width / $barcode->getWidth();

$html = '<div style="font-size:0;position:relative;width:' . $width . 'px;height:' . ($height) . 'px;">' . PHP_EOL;
$html = '<div style="font-size:0;position:relative;width:' . $width . 'px;height:' . ($height) . 'px;' . ($this->backgroundColor ? 'background-color:' . $this->backgroundColor . ';' : '') . '">' . PHP_EOL;

$positionHorizontal = 0;
/** @var BarcodeBar $bar */
Expand All @@ -36,10 +37,17 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
return $html;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setForegroundColor(string $color): self
{
$this->foregroundColor = $color;

return $this;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setBackgroundColor(?string $color): self
{
$this->backgroundColor = $color;
return $this;
}
}
10 changes: 9 additions & 1 deletion src/Renderers/JpgRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@
namespace Picqer\Barcode\Renderers;

use Imagick;
use ImagickPixel;

class JpgRenderer extends PngRenderer
{
protected function createImagickImageObject(int $width, int $height): Imagick
{
$image = new Imagick();
$image->newImage($width, $height, 'none', 'JPG');
if ($this->backgroundColor !== null) {
// Colored background
$backgroundColor = new ImagickPixel('rgb(' . implode(',', $this->backgroundColor) . ')');
} else {
// Use transparent background
$backgroundColor = new ImagickPixel('none');
}
$image->newImage($width, $height, $backgroundColor, 'JPG');

return $image;
}
Expand Down
35 changes: 30 additions & 5 deletions src/Renderers/PngRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
class PngRenderer
{
protected array $foregroundColor = [0, 0, 0];
protected ?array $backgroundColor = null;

protected bool $useImagick;

/**
Expand Down Expand Up @@ -52,6 +54,7 @@ public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30)
$width = (int)round($barcode->getWidth() * $widthFactor);

if ($this->useImagick) {
$image = $this->createImagickImageObject($width, $height);
$imagickBarsShape = new ImagickDraw();
$imagickBarsShape->setFillColor(new ImagickPixel('rgb(' . implode(',', $this->foregroundColor) .')'));
} else {
Expand Down Expand Up @@ -80,7 +83,6 @@ public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30)
}

if ($this->useImagick) {
$image = $this->createImagickImageObject($width, $height);
$image->drawImage($imagickBarsShape);
return $image->getImageBlob();
} else {
Expand All @@ -90,26 +92,49 @@ public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30)
}
}

// Use RGB color definitions, like [0, 0, 0] or [255, 255, 255]
public function setForegroundColor(array $color): self
{
$this->foregroundColor = $color;

return $this;
}

// Use RGB color definitions, like [0, 0, 0] or [255, 255, 255]
// If no color is set, the background will be transparent
public function setBackgroundColor(?array $color): self
{
$this->backgroundColor = $color;
return $this;
}

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

if ($this->backgroundColor !== null) {
// Colored background
$backgroundColor = \imagecolorallocate($image, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]);
\imagefill($image, 0, 0, $backgroundColor);
} else {
// Use transparent background
$backgroundColor = \imagecolorallocate($image, 255, 255, 255);
\imagecolortransparent($image, $backgroundColor);
}

return $image;
}

protected function createImagickImageObject(int $width, int $height): Imagick
{
$image = new Imagick();
$image->newImage($width, $height, 'none', 'PNG');
if ($this->backgroundColor !== null) {
// Colored background
$backgroundColor = new ImagickPixel('rgb(' . implode(',', $this->backgroundColor) . ')');
} else {
// Use transparent background
$backgroundColor = new ImagickPixel('none');
}
$image->newImage($width, $height, $backgroundColor, 'PNG');

return $image;
}
Expand Down
13 changes: 13 additions & 0 deletions src/Renderers/SvgRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class SvgRenderer
{
protected string $foregroundColor = 'black';
protected ?string $backgroundColor = null;
protected string $svgType = self::TYPE_SVG_STANDALONE;

public const TYPE_SVG_STANDALONE = 'standalone';
Expand All @@ -25,6 +26,12 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
}
$svg .= '<svg width="' . $width . '" height="' . $height . '" viewBox="0 0 ' . $width . ' ' . $height . '" version="1.1" xmlns="http://www.w3.org/2000/svg">' . PHP_EOL;
$svg .= "\t" . '<desc>' . htmlspecialchars($barcode->getBarcode()) . '</desc>' . PHP_EOL;

// Add background rectangle if backgroundColor is set
if ($this->backgroundColor !== null) {
$svg .= "\t" . '<rect id="background" width="100%" height="100%" fill="' . $this->backgroundColor . '"/>' . PHP_EOL;
}

$svg .= "\t" . '<g id="bars" fill="' . $this->foregroundColor . '" stroke="none">' . PHP_EOL;

// print bars
Expand Down Expand Up @@ -55,6 +62,12 @@ public function setForegroundColor(string $color): self
return $this;
}

public function setBackgroundColor(?string $color): self
{
$this->backgroundColor = $color;
return $this;
}

public function setSvgType(string $svgType): self
{
if (! in_array($svgType, [self::TYPE_SVG_INLINE, self::TYPE_SVG_STANDALONE])) {
Expand Down
11 changes: 11 additions & 0 deletions tests/HtmlRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,15 @@ public function test_html_barcode_generator_can_generate_imb_barcode_to_test_hei

$this->assertStringEqualsFile('tests/verified-files/12345678903-imb.html', $generated);
}

public function test_html_barcode_generator_with_background()
{
$barcode = (new Picqer\Barcode\Types\TypeCode128())->getBarcode('081231723897');

$renderer = new Picqer\Barcode\Renderers\HtmlRenderer();
$renderer->setBackgroundColor('red');
$generated = $renderer->render($barcode, $barcode->getWidth() * 2);

$this->assertStringEqualsFile('tests/verified-files/081231723897-code128-red-background.html', $generated);
}
}
11 changes: 11 additions & 0 deletions tests/SvgRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,15 @@ public function test_svg_renderer_throws_exception_wrong_type()
$renderer = new Picqer\Barcode\Renderers\SvgRenderer();
$renderer->setSvgType('other');
}

public function test_svg_barcode_generator_can_use_background_color()
{
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode('081231723897');

$renderer = new Picqer\Barcode\Renderers\SvgRenderer();
$renderer->setBackgroundColor('red');
$generated = $renderer->render($barcode, 190);

$this->assertStringEqualsFile('tests/verified-files/081231723897-ean13-red-background.svg', $generated);
}
}
30 changes: 30 additions & 0 deletions tests/verified-files/081231723897-code128-red-background.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div style="font-size:0;position:relative;width:202px;height:30px;background-color:red;">
<div style="background-color:black;width:4px;height:30px;position:absolute;left:0px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:6px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:12px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:22px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:30px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:38px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:44px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:48px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:56px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:66px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:72px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:82px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:88px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:94px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:106px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:110px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:118px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:128px;top:0">&nbsp;</div>
<div style="background-color:black;width:8px;height:30px;position:absolute;left:132px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:142px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:146px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:154px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:162px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:166px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:176px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:186px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:194px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:198px;top:0">&nbsp;</div>
</div>
38 changes: 38 additions & 0 deletions tests/verified-files/081231723897-ean13-red-background.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.