Tuesday, January 1, 2019

Create zebra language code in php

Zebra Programming Language (ZPL) is a page description language from Zebra Technologies, which is used for label printing. It is a command based language used by the printer as instructions for creating the images printed on the labels. Zebra language commands always start with a caret sign (^) Currently, many command exits for new version of ZPL II. In this language each format has to start with the command `^XA` and end with `^XZ` which is ANSI BASIC oriented.
So when you are working with printing application in PHP or some label printing than must use ZPL code to send to zebra printer. For FedEx, USPS, DHL and other other courier services use ZPL language for own label printing software. So when you want to work with label printing for eCommerce use than must need ZPL code for the printer.
Here you can write direct text to ZPL using start with `^XA` & end with `^XZ`. Here below example to create ZPL language from image.
For that create `Image.php` file as below

class Image
{
    protected $width;
    protected $height;
    public function __construct($image)
    {
        if (!$this->isGdResource($image)) {
            throw new InvalidArgumentException('Invalid resource');
        }
        if (!imageistruecolor($image)) {
            imagepalettetotruecolor($image);
        }
        imagefilter($image, IMG_FILTER_GRAYSCALE);
        $this->image = $image;
        $this->width = imagesx($this->image);
        $this->height = imagesy($this->image);
    }
    public function __destruct()
    {
        imagedestroy($this->image);
    }
    public function isGdResource($image)
    {
        if (is_resource($image)) {
            return get_resource_type($image) === 'gd';
        }
        return false;
    }
    public function width()
    {
        return (int)ceil($this->width / 8);
    }
    public function height()
    {
        return $this->height;
    }
    public function toAscii()
    {
        return $this->encoded ?: $this->encoded = $this->encode();
    }
    protected function encode()
    {
        $bitmap = null;
        $lastRow = null;
        for ($y = 0; $y < $this->height; $y++) {
            $bits = null;
            for ($x = 0; $x < $this->width; $x++) {
                $bits .= (imagecolorat($this->image, $x, $y) & 0xFF) < 127 ? 1 : 0;
            }
            $bytes = str_split($bits, 8);
            $bytes[] = str_pad(array_pop($bytes), 8, '0');
            $row = null;
            foreach ($bytes as $byte) {
                $row .= sprintf('%02X', bindec($byte));
            }
            $bitmap .= $this->compress($row, $lastRow);
            $lastRow = $row;
        }
        return $bitmap;
    }
    protected function compress(string $row, ?string $lastRow): string
    {
        if ($row === $lastRow) {
            return ':';
        }
        $row = $this->compressTrailingZerosOrOnes($row);
        $row = $this->compressRepeatingCharacters($row);
        return $row;
    }
    protected function compressTrailingZerosOrOnes(string $row): string
    {
        return preg_replace(['/0+$/', '/F+$/'], [',', '!'], $row);
    }
    protected function compressRepeatingCharacters(string $row): string
    {
        $callback = function ($matches) {
            $original = $matches[0];
            $repeat = strlen($original);
            $count = null;
            if ($repeat > 400) {
                $count .= str_repeat('z', floor($repeat / 400));
                $repeat %= 400;
            }
            if ($repeat > 19) {
                $count .= chr(ord('f') + floor($repeat / 20));
                $repeat %= 20;
            }
            if ($repeat > 0) {
                $count .= chr(ord('F') + $repeat);
            }
            return $count . substr($original, 1, 1);
        };
        return preg_replace_callback('/(.)(\1{2,})/', $callback, $row);
    }
}

Now create `Builder.php` file from convert image to zpl as below

class Builder
{
    protected $zpl = [];
    public function command()
    {
        $parameters = func_get_args();
        $command = strtoupper(array_shift($parameters));
        $parameters = array_map([$this, 'parameter'], $parameters);
        $this->zpl[] = '^' . $command . implode(',', $parameters);
        return $this;
    }
    protected function parameter($parameter)
    {
        if (is_bool($parameter)) {
            return $parameter ? 'Y' : 'N';
        }
        return $parameter;
    }
    public function __call($method, $arguments)
    {
        array_unshift($arguments, $method);
        return call_user_func_array([$this, 'command'], $arguments);
    }
    public function gf()
    {
        $arguments = func_get_args();
        if (func_num_args() === 1 && ($image = $arguments[0])) {
            $bytesPerRow = $image->width();
            $byteCount = $fieldCount = $bytesPerRow * $image->height();
            return $this->command('GF', 'A', $byteCount, $fieldCount, $bytesPerRow, $image->toAscii());
        }
        array_unshift($arguments, 'GF');
        return call_user_func_array([$this, 'command'], $arguments);
    }
    public function toZpl($newlines = false, $top = null, $shift = null)
    {
        $start = '^XA';
        if($top) {
            $start .= '^LT'.$top;
        }
        if($shift) {
            $start .= '^LS'.$shift;
        }
        return implode($newlines ? "\n" : '', array_merge([$start], $this->zpl, ['^XZ']));
    }
    public function __toString()
    {
        return $this->toZpl();
    }
}

After create below files convert your image file to zpl code by including both files as below.

include 'Image.php';
include 'Builder.php';
$image = new Image(imagecreatefrompng('test.png')); //You can also use imagecreatefromjpeg for jpg image
$zpl = new Builder();
echo $zpl->gf($image)->toZpl(false, 10, -10); // toZpl(Newline, Top Margin, Left Shift)

No comments :

Post a Comment