Converting RGB image to Floyd-Steinberg image using PHP or Javascript for Zebra printers
Asked Answered
E

1

7

I am developing a desktop based PHP application where we need to capture image of a person and print it on the label using Zebra GC420t printer The expected image should look like below image.

enter image description here

When I try to print the it gives the output like below image.

enter image description hereI am using the following code for the conversion of the rgb image to dithering image using php code

 $photo_url="";
if(isset($_GET['photo'])){
  $photo_url=$_GET['photo'];
}

function image2grf($filename='$photo_url', $targetname = 'R:IMAGE.GRF')
{
  $info = getimagesize($filename);
  $im = imagecreatefrompng($filename);
  $width = $info[0]; // imagesx($im);
  $height = $info[1]; // imagesy($im);
  $depth = $info['bits'] ?: 1;
  $threshold = $depth > 1 ? 160 : 0;
  $hexString = '';
  $byteShift = 7;
  $currentByte = 0;
  // iterate over all image pixels
  for ($y = 0; $y < $height; $y++) {
    for ($x = 0; $x < $width; $x++) {
      $color = imagecolorat($im, $x, $y);
      // compute gray value from RGB color
      if ($depth > 1) {
        $value = max($color >> 16, $color >> 8 & 255, $color & 255);
      } else {
        $value = $color;
      }
      // set (inverse) bit for the current pixel
      $currentByte |= (($value > $threshold ? 0 : 1) << $byteShift);
      $byteShift--;
      // 8 pixels filled one byte => append to output as hex
      if ($byteShift < 0) {
        $hexString .= sprintf('%02X', $currentByte);
        $currentByte = 0;
        $byteShift = 7;
      }
    }
    // append last byte at end of row
    if ($byteShift < 7) {
      $hexString .= sprintf('%02X', $currentByte);
      $currentByte = 0;
      $byteShift = 7;
    }
    $hexString .= PHP_EOL;
  }
  // compose ZPL ~DG command
  $totalBytes = ceil(($width * $height) / 8);
  $bytesPerRow = ceil($width / 8);
return sprintf('~DG%s,%05d,%03d,' . PHP_EOL, $targetname, $totalBytes, $bytesPerRow) . $hexString;
}
// Usage:
print "^XA N ^XZ" . PHP_EOL;
print image2grf($photo_url, 'R:SAMPLE.GRF');
//print "^XA^FO20,20^XGR:SAMPLE.GRF,1,1^FS^XZ" . PHP_EOL;

I am connecting my application and passing parameters to the printer using below javascript code

    var available_printers = null;
var selected_category = null;
var default_printer = null;
var selected_printer = null;
var format_start = "^XA^LL200^FO80,50^A0N36,36^FD";
var format_end = "^FS^XZ";
var default_mode = true;

function setup_web_print()
{
    $('#printer_select').on('change', onPrinterSelected);
    showLoading("Loading Printer Information...");
    default_mode = true;
    selected_printer = null;
    available_printers = null;
    selected_category = null;
    default_printer = null;

    BrowserPrint.getDefaultDevice('printer', function(printer)
    {
        default_printer = printer
        if((printer != null) && (printer.connection != undefined))
        {
            selected_printer = printer;
            var printer_details = $('#printer_details');
            var selected_printer_div = $('#selected_printer');

            selected_printer_div.text("Using Default Printer: " + printer.name);
            hideLoading();
            printer_details.show();
            $('#print_form').show();

        }
        BrowserPrint.getLocalDevices(function(printers)
            {
                available_printers = printers;
                var sel = document.getElementById("printers");
                var printers_available = false;
                sel.innerHTML = "";
                if (printers != undefined)
                {
                    for(var i = 0; i < printers.length; i++)
                    {
                        if (printers[i].connection == 'usb')
                        {
                            var opt = document.createElement("option");
                            opt.innerHTML = printers[i].connection + ": " + printers[i].uid;
                            opt.value = printers[i].uid;
                            sel.appendChild(opt);
                            printers_available = true;
                        }
                    }
                }

                if(!printers_available)
                {
                    showErrorMessage("No Zebra Printers could be found!");
                    hideLoading();
                    $('#print_form').hide();
                    return;
                }
                else if(selected_printer == null)
                {
                    default_mode = false;
                    changePrinter();
                    $('#print_form').show();
                    hideLoading();
                }
            }, undefined, 'printer');
    }, 
    function(error_response)
    {
        showBrowserPrintNotFound();
    });
};
function showBrowserPrintNotFound()
{
    showErrorMessage("An error occured while attempting to connect to your Zebra Printer. You may not have Zebra Browser Print installed, or it may not be running. Install Zebra Browser Print, or start the Zebra Browser Print Service, and try again.");

};
  // new Date().toLocaleTimeString('en-US', { hour12: false, 
  //                                            hour: "numeric", 
  //                                            minute: "numeric"});

function sendData(photoURL)
{

    var test;
        $.ajax({
            url: 'db/zpl.php?photo='+photoURL,
            cache: false,
            contentType: false,
            processData: false,
            type: 'GET',
            success: function(data) {
            test=data;
            console.log("From ZPL:"+data);

            }

        });



    var mob="",lap="",other="";
    if($("#emobile").val()==="on"){
        mob="Mobile";
    }

    if($("#elaptop").val()==="on"){
        lap="Laptop";
    }

    if($("#eother").val()==="on"){
        other="Other";
    }

    showLoading("Printing...");
    checkPrinterStatus( function (text){
        if (text == "Ready to Print")
        {
        selected_printer.send("^XA N ^XZ");
        selected_printer.send("~DYE:SAMPLE.GRF,A,GRF,5000,030"+test+",A");          selected_printer.send("^XA^FX^CFA,30^FO10,70^FDVisitorName:"+$("#user").val()+"^FS^FO10,120^FDCompany:"+$("#compName").val()+"^FS ^FO10,170^FDTo Meet:"+$("#toMeet").val()+"^FS ^FO10,220^FDPurpose:"+$("#reason").val()+"^FS ^FO10,270^FDAuthorise^FS ^FO10,320^FDto Carry:"+mob+" "+lap+"^FS^FO250,70^XG R:SAMPLE.GRF,1,1^FS^XZ");
        }
        else
        {
            printerError(text);
        }
    });
};

function checkPrinterStatus(finishedFunction)
{
    selected_printer.sendThenRead("~HQES", 
                function(text){
                        var that = this;
                        var statuses = new Array();
                        var ok = false;
                        var is_error = text.charAt(70);
                        var media = text.charAt(88);
                        var head = text.charAt(87);
                        var pause = text.charAt(84);
                        // check each flag that prevents printing
                        if (is_error == '0')
                        {
                            ok = true;
                            statuses.push("Ready to Print");
                        }
                        if (media == '1')
                            statuses.push("Paper out");
                        if (media == '2')
                            statuses.push("Ribbon Out");
                        if (media == '4')
                            statuses.push("Media Door Open");
                        if (media == '8')
                            statuses.push("Cutter Fault");
                        if (head == '1')
                            statuses.push("Printhead Overheating");
                        if (head == '2')
                            statuses.push("Motor Overheating");
                        if (head == '4')
                            statuses.push("Printhead Fault");
                        if (head == '8')
                            statuses.push("Incorrect Printhead");
                        if (pause == '1')
                            statuses.push("Printer Paused");
                        if ((!ok) && (statuses.Count == 0))
                            statuses.push("Error: Unknown Error");
                        finishedFunction(statuses.join());
            }, printerError);
};
function hidePrintForm()
{
    $('#print_form').hide();
};
function showPrintForm()
{
    $('#print_form').show();
};
function showLoading(text)
{
    $('#loading_message').text(text);
    $('#printer_data_loading').show();
    hidePrintForm();
    $('#printer_details').hide();
    $('#printer_select').hide();
};
function printComplete()
{
    hideLoading();
    alert ("Printing complete");
}
function hideLoading()
{
    $('#printer_data_loading').hide();
    if(default_mode == true)
    {
        showPrintForm();
        $('#printer_details').show();
    }
    else
    {
        $('#printer_select').show();
        showPrintForm();
    }
};
function changePrinter()
{
    default_mode = false;
    selected_printer = null;
    $('#printer_details').hide();
    if(available_printers == null)
    {
        showLoading("Finding Printers...");
        $('#print_form').hide();
        setTimeout(changePrinter, 200);
        return;
    }
    $('#printer_select').show();
    onPrinterSelected();
}

function onPrinterSelected()
{
    selected_printer = available_printers[$('#printers')[0].selectedIndex];
}

function showErrorMessage(text)
{
    $('#main').hide();
    $('#error_div').show();
    $('#error_message').html(text);
}

function printerError(text)
{
    showErrorMessage("An error occurred while printing. Please try again." + text);
}

function trySetupAgain()
{
    $('#main').show();
    $('#error_div').hide();
    setup_web_print();
    //hideLoading();
}

In the function below I send the parameters that are required to print

        selected_printer.send("^XA^FX^CFA,30^FO10,70^FDVisitorName:"+$("#user").val()+"^FS^FO10,120^FDCompany:"+$("#compName").val()+"^FS ^FO10,170^FDTo Meet:"+$("#toMeet").val()+"^FS ^FO10,220^FDPurpose:"+$("#reason").val()+"^FS ^FO10,270^FDAuthorise^FS ^FO10,320^FDto Carry:"+mob+" "+lap+"^FS^FO250,70^XG R:SAMPLE.GRF,1,1^FS^XZ");

In the above function the image data is stored in ^FO250,70^XG R:SAMPLE.GRF,1,1^FS

When I send the data to the printer it prints all the text properly but prints the image as shown in second image but the expected image to be print as shown in first image. I am able to print the first image if I hard code the conversion of the image done in labelary website. If I click the image in real time and print it gives second image.

Ergocalciferol answered 3/12, 2018 at 7:42 Comment(1)
P
0

Have a look at this library GDIndexedColorConverter that's a simple library that convert an image into indexed color mode.

require 'GDIndexedColorConverter.php';

// create an image
$image = imagecreatefromjpeg('image.jpg');

// create a gd indexed color converter
$converter = new GDIndexedColorConverter();

// the color palette
$palette = array(
    array(0, 0, 0),
    array(255, 255, 255),
    array(0, 0, 0),
    array(0, 0, 0),
    array(0, 0, 0)
);

// convert the image to indexed color mode
$new_image = $converter->convertToIndexedColor($image, $palette, 0.25);

// save the new image
imagepng($new_image, 'example_indexed_color.png', 0);

Here is the input:

enter image description here

And here is the output:

enter image description here

Plumage answered 31/12, 2018 at 4:54 Comment(3)
The code works but I want to store the image GRF format. As you can see the second php code where the converted code is stored in R:SAMPLE.GRF using that I will pass it to printer using javascriptErgocalciferol
Have a look at this gist gist.github.com/thomascube/9651d6fa916124a9c52cb0d4262f2c3f, i've tested the previous code myself but i'm not sure about this, but give it a try anyway .. it's not a common format.Plumage
After trying that code only I got the second image as outputErgocalciferol

© 2022 - 2024 — McMap. All rights reserved.