Преобразование изображения RGB в изображение Флойда-Стейнберга с использованием PHP или Javascript для принтеров Zebra

Я разрабатываю десктоп на основе PHP приложение, где нам нужно захватить изображение человека и распечатать его на этикетке с помощью принтера Zebra GC420t. Ожидаемое изображение должно выглядеть как на рисунке ниже.

Когда я пытаюсь распечатать, он выдает результат, как на картинке ниже.

Я использую следующий код для преобразованияrgbизображение вditheringиспользование изображения php код

 $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;

Я подключаю свое приложение и передаю параметры на принтер, используя нижеjavascriptкод

    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();
}

В функции ниже я отправляю параметры, необходимые для печати

        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");

В вышеупомянутой функции данные изображения сохраняются в^FO250,70^XG R:SAMPLE.GRF,1,1^FS

Когда я отправляю данные на принтер, он печатает весь текст правильно, но печатает изображение, как показано на втором изображении, но ожидаемое изображение будет напечатано, как показано на первом изображении. Я могу напечатать первое изображение, если я жестко запрограммировал преобразование изображения на веб- сайте. Если я нажимаю на изображение в реальном времени и печатаю, оно дает второе изображение.

1 ответ

Решение

Взгляните на эту библиотеку GDIndexedColorConverter, это простая библиотека, которая преобразует изображение в индексированный цветовой режим.

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);

Вот вход:

https://st ackru.com/images/f26bc35aa5080ee61f18c925b1de6b04dd c05d9a.jpg

И вот вывод:

https://st ackru.com/images/2d1fa475536366628d60c49fdd91c9cb34e54193.png

Другие вопросы по тегам