Copyright (c) 2014-2015 Michael Billington , incorporating modifications by: - Roni Saha - Gergely Radics - Warren Doyle Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. This class deals with images in raster formats, and converts them into formats which are suitable for use on thermal receipt printers. Currently, only PNG images (in) and ESC/POS raster format (out) are implemeted. Input formats: - Currently, only PNG is supported. - Other easily read raster formats (jpg, gif) will be added at a later date, as this is not complex. - The BMP format can be directly read by some commands, but this has not yet been implemented. Output formats: - Currently, only ESC/POS raster format is supported - ESC/POS 'column format' support is partially implemented, but is not yet used by Escpos.php library. - Output as multiple rows of column format image is not yet in the works. Libraries: - Currently, php-gd is used to read the input. Support for imagemagick where gd is not installed is also not complex to add, and is a likely future feature. - Support for native use of the BMP format is a goal, for maximum compatibility with target environments.
Example #1
1
<?php

/* Print-outs using the newer graphics print command */
require __DIR__ . '/../autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("php://stdout");
$printer = new Printer($connector);
try {
    $tux = EscposImage::load("resources/tux.png", false);
    $printer->graphics($tux);
    $printer->text("Regular Tux.\n");
    $printer->feed();
    $printer->graphics($tux, Printer::IMG_DOUBLE_WIDTH);
    $printer->text("Wide Tux.\n");
    $printer->feed();
    $printer->graphics($tux, Printer::IMG_DOUBLE_HEIGHT);
    $printer->text("Tall Tux.\n");
    $printer->feed();
    $printer->graphics($tux, Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT);
    $printer->text("Large Tux in correct proportion.\n");
    $printer->cut();
} catch (Exception $e) {
    /* Images not supported on your PHP, or image file not found */
    $printer->text($e->getMessage() . "\n");
}
$printer->close();
Example #2
0
 /**
  * Load actual image pixels from GD resource.
  *
  * @param resource $im GD resource to use
  * @throws Exception Where the image can't be read.
  */
 public function readImageFromGdResource($im)
 {
     if (!is_resource($im)) {
         throw new Exception("Failed to load image.");
     } elseif (!EscposImage::isGdLoaded()) {
         throw new Exception(__FUNCTION__ . " requires 'gd' extension.");
     }
     /* Make a string of 1's and 0's */
     $imgHeight = imagesy($im);
     $imgWidth = imagesx($im);
     $imgData = str_repeat("", $imgHeight * $imgWidth);
     for ($y = 0; $y < $imgHeight; $y++) {
         for ($x = 0; $x < $imgWidth; $x++) {
             /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */
             $cols = imagecolorsforindex($im, imagecolorat($im, $x, $y));
             // 1 for white, 0 for black, ignoring transparency
             $greyness = (int) (($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7;
             // 1 for black, 0 for white, taking into account transparency
             $black = 1 - $greyness >> ($cols['alpha'] >> 6);
             $imgData[$y * $imgWidth + $x] = $black;
         }
     }
     $this->setImgWidth($imgWidth);
     $this->setImgHeight($imgHeight);
     $this->setImgData($imgData);
 }
Example #3
0
 public function __construct()
 {
     if (!EscposImage::isImagickLoaded()) {
         throw new Exception("ImagePrintBuffer requires the imagick extension");
     }
     $this->font = null;
     $this->fontSize = 24;
 }
Example #4
0
        /* Read stdout */
        $outputStr = stream_get_contents($fd[1]);
        fclose($fd[1]);
        /* Read stderr */
        $errorStr = stream_get_contents($fd[2]);
        fclose($fd[2]);
        /* Finish up */
        $retval = proc_close($process);
        if ($retval != 0) {
            throw new Exception("Command {$cmd} failed: {$outputStr} {$errorStr}");
        }
    } else {
        throw new Exception("Command '{$cmd}' failed to start.");
    }
    /* Load up the image */
    try {
        $img = EscposImage::load($dest);
    } catch (Exception $e) {
        unlink($dest);
        throw $e;
    }
    unlink($dest);
    /* Print it */
    $printer->bitImage($img);
    // bitImage() seems to allow larger images than graphics() on the TM-T20. bitImageColumnFormat() is another option.
    $printer->cut();
} catch (Exception $e) {
    echo $e->getMessage();
} finally {
    $printer->close();
}
Example #5
0
 /**
  * Print an image to the printer.
  * 
  * Size modifiers are:
  * - IMG_DEFAULT (leave image at original size)
  * - IMG_DOUBLE_WIDTH
  * - IMG_DOUBLE_HEIGHT
  * 
  * See the example/ folder for detailed examples.
  * 
  * The function bitImage() takes the same parameters, and can be used if
  * your printer doesn't support the newer graphics commands.
  * 
  * @param EscposImage $img The image to print.
  * @param int $size Output size modifier for the image.
  */
 function graphics(EscposImage $img, $size = self::IMG_DEFAULT)
 {
     self::validateInteger($size, 0, 3, __FUNCTION__);
     $imgHeader = self::dataHeader(array($img->getWidth(), $img->getHeight()), true);
     $tone = '0';
     $colors = '1';
     $xm = ($size & self::IMG_DOUBLE_WIDTH) == self::IMG_DOUBLE_WIDTH ? chr(2) : chr(1);
     $ym = ($size & self::IMG_DOUBLE_HEIGHT) == self::IMG_DOUBLE_HEIGHT ? chr(2) : chr(1);
     $header = $tone . $xm . $ym . $colors . $imgHeader;
     $this->wrapperSendGraphicsData('0', 'p', $header . $img->toRasterFormat());
     $this->wrapperSendGraphicsData('0', '2');
 }
Example #6
0
 function writeText($text)
 {
     if ($this->printer == null) {
         throw new LogicException("Not attached to a printer.");
     }
     if ($text == null) {
         return;
     }
     $text = trim($text, "\n");
     /* Create Imagick objects */
     $image = new \Imagick();
     $draw = new \ImagickDraw();
     $color = new \ImagickPixel('#000000');
     $background = new \ImagickPixel('white');
     /* Create annotation */
     //$draw -> setFont('Arial');// (not necessary?)
     $draw->setFontSize(24);
     // Size 21 looks good for FONT B
     $draw->setFillColor($color);
     $draw->setStrokeAntialias(true);
     $draw->setTextAntialias(true);
     $metrics = $image->queryFontMetrics($draw, $text);
     $draw->annotation(0, $metrics['ascender'], $text);
     /* Create image & draw annotation on it */
     $image->newImage($metrics['textWidth'], $metrics['textHeight'], $background);
     $image->setImageFormat('png');
     $image->drawImage($draw);
     //$image -> writeImage("test.png");
     /* Save image */
     $escposImage = new EscposImage();
     $escposImage->readImageFromImagick($image);
     $size = Printer::IMG_DEFAULT;
     $this->printer->bitImage($escposImage, $size);
 }
Example #7
0
 /**
  * Load a PDF for use on the printer
  *
  * @param string $pdfFile The file to load
  * @param string $pageWidth The width, in pixels, of the printer's output. The first page of the PDF will be scaled to approximately fit in this area.
  * @param array $range array indicating the first and last page (starting from 0) to load. If not set, the entire document is loaded.
  * @throws Exception Where Imagick is not loaded, or where a missing file or invalid page number is requested.
  * @return multitype:EscposImage Array of images, retrieved from the PDF file.
  */
 public static function loadPdf($pdfFile, $pageWidth = 550, array $range = null)
 {
     if (!extension_loaded('imagick')) {
         throw new Exception(__FUNCTION__ . " requires imagick extension.");
     }
     /*
      * Load first page at very low density (resolution), to figure out what
      * density to use to achieve $pageWidth
      */
     try {
         $image = new Imagick();
         $testRes = 2;
         // Test resolution
         $image->setresolution($testRes, $testRes);
         $image->readimage($pdfFile . "[0]");
         $geo = $image->getimagegeometry();
         $image->destroy();
         $width = $geo['width'];
         $newRes = $pageWidth / $width * $testRes;
         /* Load actual document (can be very slow!) */
         $rangeStr = "";
         // Set to [0] [0-1] page range if $range is set
         if ($range != null) {
             if (count($range) != 2 || !isset($range[0]) || !is_integer($range[0]) || !isset($range[1]) || !is_integer($range[1]) || $range[0] > $range[1]) {
                 throw new Exception("Invalid range. Must be two numbers in the array: The start and finish page indexes, starting from 0.");
             }
             $rangeStr = "[" . ($range[0] == $range[1] ? $range[0] : implode($range, "-")) . "]";
         }
         $image->setresolution($newRes, $newRes);
         $image->readImage($pdfFile . "{$rangeStr}");
         $pages = $image->getNumberImages();
         /* Convert images to Escpos objects */
         $ret = array();
         for ($i = 0; $i < $pages; $i++) {
             $image->setIteratorIndex($i);
             $ep = new EscposImage();
             $ep->readImageFromImagick($image);
             $ret[] = $ep;
         }
         return $ret;
     } catch (ImagickException $e) {
         // Wrap in normal exception, so that classes which call this do not themselves require imagick as a dependency.
         throw new Exception($e);
     }
 }
Example #8
0
 protected function requireGraphicsLibrary()
 {
     if (!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) {
         $this->markTestSkipped("This test requires a graphics library.");
     }
 }
Example #9
0
 /**
  * Load a PDF for use on the printer
  *
  * @param string $pdfFile
  *  The file to load
  * @param string $pageWidth
  *  The width, in pixels, of the printer's output. The first page of the
  *  PDF will be scaled to approximately fit in this area.
  * @throws Exception Where Imagick is not loaded, or where a missing file
  *  or invalid page number is requested.
  * @return multitype:EscposImage Array of images, retrieved from the PDF file.
  */
 public static function loadPdf($pdfFile, $pageWidth = 550)
 {
     if (!EscposImage::isImagickLoaded()) {
         throw new Exception(__FUNCTION__ . " requires imagick extension.");
     }
     /*
      * Load first page at very low density (resolution), to figure out what
      * density to use to achieve $pageWidth
      */
     try {
         $image = new \Imagick();
         $testRes = 2;
         // Test resolution
         $image->setresolution($testRes, $testRes);
         /* Load document just to measure geometry */
         $image->readimage($pdfFile);
         $geo = $image->getimagegeometry();
         $image->destroy();
         $width = $geo['width'];
         $newRes = $pageWidth / $width * $testRes;
         /* Load entire document in */
         $image->setresolution($newRes, $newRes);
         $image->readImage($pdfFile);
         $pages = $image->getNumberImages();
         /* Convert images to Escpos objects */
         $ret = array();
         for ($i = 0; $i < $pages; $i++) {
             $image->setIteratorIndex($i);
             $ep = new ImagickEscposImage();
             $ep->readImageFromImagick($image);
             $ret[] = $ep;
         }
         return $ret;
     } catch (\ImagickException $e) {
         /* Wrap in normal exception, so that classes which call this do not
          * themselves require imagick as a dependency. */
         throw new Exception($e);
     }
 }
Example #10
0
 public function testImageNotSupportedException()
 {
     $this->setExpectedException('InvalidArgumentException');
     $img = EscposImage::load('/dev/null', false, array());
 }
Example #11
-1
require __DIR__ . '/../autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
/* Fill in your own connector here */
$connector = new FilePrintConnector("php://stdout");
/* Information for the receipt */
$items = array(new item("Example item #1", "4.00"), new item("Another thing", "3.50"), new item("Something else", "1.00"), new item("A final item", "4.45"));
$subtotal = new item('Subtotal', '12.95');
$tax = new item('A local tax', '1.30');
$total = new item('Total', '14.25', true);
/* Date is kept the same for testing */
// $date = date('l jS \of F Y h:i:s A');
$date = "Monday 6th of April 2015 02:56:25 PM";
/* Start the printer */
$logo = EscposImage::load("resources/escpos-php.png", false);
$printer = new Printer($connector);
/* Print top logo */
$printer->setJustification(Printer::JUSTIFY_CENTER);
$printer->graphics($logo);
/* Name of shop */
$printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
$printer->text("ExampleMart Ltd.\n");
$printer->selectPrintMode();
$printer->text("Shop No. 42.\n");
$printer->feed();
/* Title of receipt */
$printer->setEmphasis(true);
$printer->text("SALES INVOICE\n");
$printer->setEmphasis(false);
/* Items */
Example #12
-2
<?php

/*
 * Example of dithering used in EscposImage by default, if you have Imagick loaded.
 */
require __DIR__ . '/../../autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);
try {
    /*  Load with optimisations enabled. If you have Imagick, this will get you
            a nicely dithered image, which prints very quickly
        */
    $img1 = EscposImage::load(__DIR__ . '/../resources/tulips.png');
    $printer->bitImage($img1);
    /*  Load with optimisations disabled, forcing the use of PHP to convert the
            pixels, which uses a threshold and is much slower.
        */
    $img2 = EscposImage::load(__DIR__ . '/../resources/tulips.png', false);
    $printer->bitImage($img2);
    $printer->cut();
} finally {
    /* Always close the printer! */
    $printer->close();
}