Skip to content

Commit 3ef0b26

Browse files
authored
Merge pull request #206 from picqer/interface
Add a RendererInterface
2 parents 5fd1162 + d06a28f commit 3ef0b26

File tree

64 files changed

+406
-326
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+406
-326
lines changed

Readme.md

+22-13
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Install through [composer](https://getcomposer.org/doc/00-intro.md):
1818
composer require picqer/php-barcode-generator
1919
```
2020

21-
If you want to generate PNG or JPG images, you need the GD library or Imagick installed on your system as well.
21+
If you want to generate PNG or JPG images, you need the GD library or Imagick installed on your system as well. For SVG or HTML renders, there are no dependencies.
2222

2323
## Usage
2424
You want a barcode for a specific "type" (for example Code 128 or UPC) in a specific image format (for example PNG or SVG).
@@ -54,21 +54,28 @@ $barcode = (new Picqer\Barcode\Types\TypeCode128())->getBarcode('081231723897');
5454
$renderer = new Picqer\Barcode\Renderers\PngRenderer();
5555
$renderer->setForegroundColor($colorRed);
5656

57-
// Save PNG to the filesystem, with widthFactor 3 and height of 50 pixels
58-
file_put_contents('barcode.png', $renderer->render($barcode, 3, 50));
57+
// Save PNG to the filesystem, with widthFactor 3 (width of the barcode x 3) and height of 50 pixels
58+
file_put_contents('barcode.png', $renderer->render($barcode, $barcode->getWidth() * 3, 50));
5959
```
6060

6161
## Image renderers
6262
Available image renderers: SVG, PNG, JPG and HTML.
6363

64-
Each renderer has their own options. Only the barcode is required, the rest is optional. Here are all the options for each renderers:
64+
They all conform to the RendererInterface and have the same `render()` method. Some renderers have extra options as well, via set*() methods.
65+
66+
### Widths
67+
The render() method needs the Barcode object, the width and height. **For JPG/PNG images**, you only get a valid barcode if you give a width that is a factor of the width of the Barcode object. That is why the examples show `$barcode->getWidth() * 2` to make the image 2 times wider in pixels then the width of the barcode data. You *can* give an arbitrary number as width and the image will be scaled as best as possible, but without anti-aliasing, it will not be perfectly valid.
68+
69+
HTML and SVG renderers can handle any width and height, even floats.
70+
71+
Here are all the options for each renderer:
6572

6673
### SVG
6774
A vector based SVG image. Gives the best quality to print.
6875
```php
6976
$renderer = new Picqer\Barcode\Renderers\SvgRenderer();
70-
$renderer->setForegroundColor('red'); // Give a color for the bars, default is black
71-
$renderer->setBackgroundColor('blue'); // Give a color for the background, default is transparent
77+
$renderer->setForegroundColor([255, 0, 0]); // Give a color red for the bars, default is black. Give it as 3 times 0-255 values for red, green and blue.
78+
$renderer->setBackgroundColor([0, 0, 255]); // Give a color blue for the background, default is transparent. Give it as 3 times 0-255 values for red, green and blue.
7279
$renderer->setSvgType($renderer::TYPE_SVG_INLINE); // Changes the output to be used inline inside HTML documents, instead of a standalone SVG image (default)
7380
$renderer->setSvgType($renderer::TYPE_SVG_STANDALONE); // If you want to force the default, create a stand alone SVG image
7481

@@ -91,8 +98,8 @@ $renderer->render($barcode, 5, 40); // Width factor (how many pixel wide every b
9198
Gives HTML to use inline in a full HTML document.
9299
```php
93100
$renderer = new Picqer\Barcode\Renderers\HtmlRenderer();
94-
$renderer->setForegroundColor('red'); // Give a color for the bars, default is black
95-
$renderer->setBackgroundColor('blue'); // Give a color for the background, default is transparent
101+
$renderer->setForegroundColor([255, 0, 0]); // Give a color red for the bars, default is black. Give it as 3 times 0-255 values for red, green and blue.
102+
$renderer->setBackgroundColor([0, 0, 255]); // Give a color blue for the background, default is transparent. Give it as 3 times 0-255 values for red, green and blue.
96103

97104
$renderer->render($barcode, 450.20, 75); // Width and height support floats
98105
````
@@ -101,8 +108,8 @@ $renderer->render($barcode, 450.20, 75); // Width and height support floats
101108
Give HTML here the barcode is using the full width and height, to put inside a container/div that has a fixed size.
102109
```php
103110
$renderer = new Picqer\Barcode\Renderers\DynamicHtmlRenderer();
104-
$renderer->setForegroundColor('red'); // Give a color for the bars, default is black
105-
$renderer->setBackgroundColor('blue'); // Give a color for the background, default is transparent
111+
$renderer->setForegroundColor([255, 0, 0]); // Give a color red for the bars, default is black. Give it as 3 times 0-255 values for red, green and blue.
112+
$renderer->setBackgroundColor([0, 0, 255]); // Give a color blue for the background, default is transparent. Give it as 3 times 0-255 values for red, green and blue.
106113

107114
$renderer->render($barcode);
108115
````
@@ -163,15 +170,15 @@ If you want to use PNG or JPG images, you need to install [Imagick](https://www.
163170
```php
164171
$barcode = (new Picqer\Barcode\Types\TypeCode128())->getBarcode('081231723897');
165172
$renderer = new Picqer\Barcode\Renderers\PngRenderer();
166-
echo '<img src="data:image/png;base64,' . base64_encode($renderer->render($barcode)) . '">';
173+
echo '<img src="data:image/png;base64,' . base64_encode($renderer->render($barcode, $barcode->getWidth() * 2)) . '">';
167174
```
168175

169176
### Save JPG barcode to disk
170177
```php
171178
$barcode = (new Picqer\Barcode\Types\TypeCodabar())->getBarcode('081231723897');
172179
$renderer = new Picqer\Barcode\Renderers\JpgRenderer();
173180

174-
file_put_contents('barcode.jpg', $renderer->render($barcode));
181+
file_put_contents('barcode.jpg', $renderer->render($barcode, $barcode->getWidth() * 2));
175182
```
176183

177184
### Oneliner SVG output to disk
@@ -182,6 +189,8 @@ file_put_contents('barcode.svg', (new Picqer\Barcode\Renderers\SvgRenderer())->r
182189
## Upgrading to v3
183190
There is no need to change anything when upgrading from v2 to v3. Above you find the new preferred way of using this library since v3. But the old style still works.
184191

192+
To give the renderers the same interface, setting colors is now always with an array of RGB colors. If you use the old BarcodeGenerator* classes and use colors with names ('red') or hex codes (#3399ef), these will be converted using the ColorHelper. All hexcodes are supported, but for names of colors only the basic colors are supported.
193+
185194
If you want to convert to the new style, here is an example:
186195
```php
187196
// Old style
@@ -194,7 +203,7 @@ $renderer = new Picqer\Barcode\Renderers\SvgRenderer();
194203
echo $renderer->render($barcode);
195204
```
196205

197-
The width in the SVG and HTML renderer is now the width of the end result, instead of the widthFactor. If you want to keep dynamic widths, you can get the width of the encoded Barcode and multiply it by the widthFactor to get the same result as before. See here an example for a widthFactor of 2:
206+
The width in the renderer is now the width of the end result, instead of the widthFactor. If you want to keep dynamic widths, you can get the width of the encoded Barcode and multiply it by the widthFactor to get the same result as before. See here an example for a widthFactor of 2:
198207
```php
199208
// Old style
200209
$generator = new Picqer\Barcode\BarcodeGeneratorSVG();

generate-verified-files.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
file_put_contents('tests/verified-files/081231723897-ean13-fractional-width.svg', $svgRenderer->render($barcode, $barcode->getWidth() * 0.25, 25.75));
1616

1717
$svgRendererRed = new Picqer\Barcode\Renderers\SvgRenderer();
18-
$svgRendererRed->setBackgroundColor('red');
18+
$svgRendererRed->setBackgroundColor([255, 0, 0]);
1919
file_put_contents('tests/verified-files/081231723897-ean13-red-background.svg', $svgRendererRed->render($barcode, $barcode->getWidth() * 2));
2020

2121
$barcode = $typeEncoderCode128->getBarcode('081231723897');
2222
file_put_contents('tests/verified-files/081231723897-code128.html', $htmlRenderer->render($barcode, $barcode->getWidth() * 2));
2323
$htmlRendererRed = new Picqer\Barcode\Renderers\HtmlRenderer();
24-
$htmlRendererRed->setBackgroundColor('red');
24+
$htmlRendererRed->setBackgroundColor([255, 0, 0]);
2525
file_put_contents('tests/verified-files/081231723897-code128-red-background.html', $htmlRendererRed->render($barcode, $barcode->getWidth() * 2));
2626

2727
$barcode = $typeEncoderIMB->getBarcode('12345678903');

src/BarcodeGeneratorDynamicHTML.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Picqer\Barcode;
44

55
use Picqer\Barcode\Exceptions\UnknownTypeException;
6+
use Picqer\Barcode\Helpers\ColorHelper;
67

78
class BarcodeGeneratorDynamicHTML extends BarcodeGenerator
89
{
@@ -21,7 +22,7 @@ public function getBarcode(string $barcode, $type, string $foregroundColor = 'bl
2122
$barcodeData = $this->getBarcodeData($barcode, $type);
2223

2324
$renderer = new \Picqer\Barcode\Renderers\DynamicHtmlRenderer();
24-
$renderer->setForegroundColor($foregroundColor);
25+
$renderer->setForegroundColor(ColorHelper::getArrayFromColorString($foregroundColor));
2526

2627
return $renderer->render($barcodeData);
2728
}

src/BarcodeGeneratorHTML.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Picqer\Barcode;
44

55
use Picqer\Barcode\Exceptions\UnknownTypeException;
6+
use Picqer\Barcode\Helpers\ColorHelper;
67

78
class BarcodeGeneratorHTML extends BarcodeGenerator
89
{
@@ -25,7 +26,7 @@ public function getBarcode(string $barcode, $type, int $widthFactor = 2, int $he
2526
$width = round(($barcodeData->getWidth() * $widthFactor), 3);
2627

2728
$renderer = new \Picqer\Barcode\Renderers\HtmlRenderer();
28-
$renderer->setForegroundColor($foregroundColor);
29+
$renderer->setForegroundColor(ColorHelper::getArrayFromColorString($foregroundColor));
2930

3031
return $renderer->render($barcodeData, $width, $height);
3132
}

src/BarcodeGeneratorJPG.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function getBarcode(string $barcode, $type, int $widthFactor = 2, int $he
3434
}
3535
}
3636

37-
return $renderer->render($barcodeData, $widthFactor, $height);
37+
return $renderer->render($barcodeData, $barcodeData->getWidth() * $widthFactor, $height);
3838
}
3939

4040
/**

src/BarcodeGeneratorPNG.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function getBarcode(string $barcode, $type, int $widthFactor = 2, int $he
3434
}
3535
}
3636

37-
return $renderer->render($barcodeData, $widthFactor, $height);
37+
return $renderer->render($barcodeData, $barcodeData->getWidth() * $widthFactor, $height);
3838
}
3939

4040
/**

src/BarcodeGeneratorSVG.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Picqer\Barcode;
44

55
use Picqer\Barcode\Exceptions\UnknownTypeException;
6+
use Picqer\Barcode\Helpers\ColorHelper;
67

78
class BarcodeGeneratorSVG extends BarcodeGenerator
89
{
@@ -25,7 +26,7 @@ public function getBarcode(string $barcode, $type, float $widthFactor = 2, float
2526
$width = round(($barcodeData->getWidth() * $widthFactor), 3);
2627

2728
$renderer = new \Picqer\Barcode\Renderers\SvgRenderer();
28-
$renderer->setForegroundColor($foregroundColor);
29+
$renderer->setForegroundColor(ColorHelper::getArrayFromColorString($foregroundColor));
2930

3031
return $renderer->render($barcodeData, $width, $height);
3132
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
namespace Picqer\Barcode\Exceptions;
4+
5+
class UnknownColorException extends BarcodeException {}

src/Helpers/ColorHelper.php

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace Picqer\Barcode\Helpers;
4+
5+
use Picqer\Barcode\Exceptions\UnknownColorException;
6+
7+
class ColorHelper
8+
{
9+
// Convert textual color values, to array of 3 colors 0-255
10+
// Can be "red", "#333" or "#009945" styles
11+
public static function getArrayFromColorString(string $color): array {
12+
if ($color == 'black') {
13+
return [0, 0, 0];
14+
} elseif ($color == 'white') {
15+
return [255, 255, 255];
16+
} elseif ($color == 'red') {
17+
return [255, 0, 0];
18+
} elseif ($color == 'green') {
19+
return [0, 255, 0];
20+
} elseif ($color == 'blue') {
21+
return [0, 0, 255];
22+
} elseif ($color == 'yellow') {
23+
return [255, 255, 0];
24+
}
25+
26+
// #333 style
27+
if (str_starts_with($color, '#') && strlen($color) === 4) {
28+
return [
29+
hexdec(substr($color, 1, 1) . substr($color, 1, 1)),
30+
hexdec(substr($color, 2, 1) . substr($color, 2, 1)),
31+
hexdec(substr($color, 3, 1) . substr($color, 3, 1)),
32+
];
33+
}
34+
35+
// #009933 style
36+
if (str_starts_with($color, '#') && strlen($color) === 7) {
37+
return [
38+
hexdec(substr($color, 1, 2)),
39+
hexdec(substr($color, 2, 2)),
40+
hexdec(substr($color, 3, 2)),
41+
];
42+
}
43+
44+
throw new UnknownColorException('Only basic string-based colors are supported in v3.');
45+
}
46+
}

src/Renderers/DynamicHtmlRenderer.php

+9-10
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
use Picqer\Barcode\Barcode;
66
use Picqer\Barcode\BarcodeBar;
77

8-
class DynamicHtmlRenderer
8+
class DynamicHtmlRenderer implements RendererInterface
99
{
1010
protected const WIDTH_PRECISION = 6;
1111

12-
protected string $foregroundColor = 'black';
13-
protected ?string $backgroundColor = null;
12+
protected array $foregroundColor = [0, 0, 0];
13+
protected ?array $backgroundColor = null;
1414

15-
public function render(Barcode $barcode): string
15+
// Width and height are ignored in this renderer
16+
public function render(Barcode $barcode, float $width = 200, float $height = 30): string
1617
{
17-
$html = '<div style="font-size:0;position:relative;width:100%;height:100%' . ($this->backgroundColor ? ';background-color:' . $this->backgroundColor : '') . '">' . PHP_EOL;
18+
$html = '<div style="font-size:0;position:relative;width:100%;height:100%' . ($this->backgroundColor ? ';background-color:rgb(' . implode(',', $this->backgroundColor) . ')' : '') . '">' . PHP_EOL;
1819

1920
$positionHorizontal = 0;
2021
/** @var BarcodeBar $bar */
@@ -26,7 +27,7 @@ public function render(Barcode $barcode): string
2627
$positionVertical = round(($bar->getPositionVertical() / $barcode->getHeight() * 100), 3);
2728

2829
// draw a vertical bar
29-
$html .= '<div style="background-color:' . $this->foregroundColor . ';width:' . round($barWidth, self::WIDTH_PRECISION) . '%;height:' . $barHeight . '%;position:absolute;left:' . round($positionHorizontal, self::WIDTH_PRECISION) . '%;top:' . $positionVertical . (($positionVertical > 0) ? '%' : '') . '">&nbsp;</div>' . PHP_EOL;
30+
$html .= '<div style="background-color:rgb(' . implode(',', $this->foregroundColor) . ');width:' . round($barWidth, self::WIDTH_PRECISION) . '%;height:' . $barHeight . '%;position:absolute;left:' . round($positionHorizontal, self::WIDTH_PRECISION) . '%;top:' . $positionVertical . (($positionVertical > 0) ? '%' : '') . '">&nbsp;</div>' . PHP_EOL;
3031
}
3132

3233
$positionHorizontal += $barWidth;
@@ -37,15 +38,13 @@ public function render(Barcode $barcode): string
3738
return $html;
3839
}
3940

40-
// Use HTML color definitions, like 'red' or '#ff0000'
41-
public function setForegroundColor(string $color): self
41+
public function setForegroundColor(array $color): self
4242
{
4343
$this->foregroundColor = $color;
4444
return $this;
4545
}
4646

47-
// Use HTML color definitions, like 'red' or '#ff0000'
48-
public function setBackgroundColor(?string $color): self
47+
public function setBackgroundColor(?array $color): self
4948
{
5049
$this->backgroundColor = $color;
5150
return $this;

src/Renderers/HtmlRenderer.php

+7-9
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
use Picqer\Barcode\Barcode;
66
use Picqer\Barcode\BarcodeBar;
77

8-
class HtmlRenderer
8+
class HtmlRenderer implements RendererInterface
99
{
10-
protected string $foregroundColor = 'black';
11-
protected ?string $backgroundColor = null;
10+
protected array $foregroundColor = [0, 0, 0];
11+
protected ?array $backgroundColor = null;
1212

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

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

1919
$positionHorizontal = 0;
2020
/** @var BarcodeBar $bar */
@@ -26,7 +26,7 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
2626
$positionVertical = round(($bar->getPositionVertical() * $height / $barcode->getHeight()), 3);
2727

2828
// draw a vertical bar
29-
$html .= '<div style="background-color:' . $this->foregroundColor . ';width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . (($positionVertical > 0) ? 'px' : '') . '">&nbsp;</div>' . PHP_EOL;
29+
$html .= '<div style="background-color:rgb(' . implode(',', $this->foregroundColor) . ');width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . (($positionVertical > 0) ? 'px' : '') . '">&nbsp;</div>' . PHP_EOL;
3030
}
3131

3232
$positionHorizontal += $barWidth;
@@ -37,15 +37,13 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
3737
return $html;
3838
}
3939

40-
// Use HTML color definitions, like 'red' or '#ff0000'
41-
public function setForegroundColor(string $color): self
40+
public function setForegroundColor(array $color): self
4241
{
4342
$this->foregroundColor = $color;
4443
return $this;
4544
}
4645

47-
// Use HTML color definitions, like 'red' or '#ff0000'
48-
public function setBackgroundColor(?string $color): self
46+
public function setBackgroundColor(?array $color): self
4947
{
5048
$this->backgroundColor = $color;
5149
return $this;

src/Renderers/PngRenderer.php

+12-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Picqer\Barcode\BarcodeBar;
1010
use Picqer\Barcode\Exceptions\BarcodeException;
1111

12-
class PngRenderer
12+
class PngRenderer implements RendererInterface
1313
{
1414
protected array $foregroundColor = [0, 0, 0];
1515
protected ?array $backgroundColor = null;
@@ -49,9 +49,15 @@ public function useGd(): self
4949
return $this;
5050
}
5151

52-
public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30): string
52+
// Floats in width and height will be rounded to integers
53+
// For best (and valid) result, use a width as a factor of the width of the Barcode object
54+
// Example: $width = $barcode->getWidth() * 3
55+
public function render(Barcode $barcode, float $width = 200, float $height = 30): string
5356
{
54-
$width = (int)round($barcode->getWidth() * $widthFactor);
57+
$width = (int)round($width);
58+
$height = (int)round($height);
59+
60+
$widthFactor = $width / $barcode->getWidth();
5561

5662
if ($this->useImagick) {
5763
$image = $this->createImagickImageObject($width, $height);
@@ -66,17 +72,17 @@ public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30)
6672
$positionHorizontal = 0;
6773
/** @var BarcodeBar $bar */
6874
foreach ($barcode->getBars() as $bar) {
69-
$barWidth = (int)round(($bar->getWidth() * $widthFactor));
75+
$barWidth = $bar->getWidth() * $widthFactor;
7076

7177
if ($bar->isBar() && $barWidth > 0) {
7278
$y = (int)round(($bar->getPositionVertical() * $height / $barcode->getHeight()));
7379
$barHeight = (int)round(($bar->getHeight() * $height / $barcode->getHeight()));
7480

7581
// draw a vertical bar
7682
if ($this->useImagick) {
77-
$imagickBarsShape->rectangle($positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight));
83+
$imagickBarsShape->rectangle((int)round($positionHorizontal), $y, (int)round($positionHorizontal + $barWidth - 1), ($y + $barHeight));
7884
} else {
79-
\imagefilledrectangle($image, $positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight), $gdForegroundColor);
85+
\imagefilledrectangle($image, (int)round($positionHorizontal), $y, (int)round($positionHorizontal + $barWidth - 1), ($y + $barHeight), $gdForegroundColor);
8086
}
8187
}
8288
$positionHorizontal += $barWidth;

src/Renderers/RendererInterface.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Picqer\Barcode\Renderers;
4+
5+
use Picqer\Barcode\Barcode;
6+
7+
interface RendererInterface
8+
{
9+
public function render(Barcode $barcode, float $width = 200, float $height = 30): string;
10+
11+
public function setForegroundColor(array $color): self;
12+
13+
public function setBackgroundColor(?array $color): self;
14+
}

0 commit comments

Comments
 (0)