Search code examples
c#bitmapzebra-printerswindows-mobile-6.5

Printing Image to Zebra iMZ320


Platform: Windows Mobile 6.5 Handheld

Language: C#

My problem: I'm being asked to capture a signature from the user and then send that signature to a printer to print on a receipt. I've successfully captured the image of the signature and have the byte array of the signature in memory but cannot seem to print it properly.

To get me started, I followed the blog here to get the Hex representation of the bitmap. However, this just printed out a very long receipt with the hex representation of the signature. Code here instead of following the link:

    private static string DrawBitmap(Bitmap bmp, int xPosition, int yPosition)
    {
        if (bmp == null)
            throw new ArgumentNullException("bmp");

        StringBuilder DataString = new StringBuilder();
        //Make sure the width is divisible by 8
        int loopWidth = 8 - (bmp.Width % 8);
        if (loopWidth == 8)
            loopWidth = bmp.Width;
        else
            loopWidth += bmp.Width;

        //DataString.Append(string.Format("EG {0} {1} {2} {3} ", xPosition, yPosition));
        DataString.Append(string.Format("EG 64 128 {0} {1} ", xPosition, yPosition));

        for (int y = 0; y < bmp.Height; y++)
        {
            int bit = 128;
            int currentValue = 0;
            for (int x = 0; x < loopWidth; x++)
            {
                int intensity;

                if (x < bmp.Width)
                {
                    Color color = bmp.GetPixel(x, y);
                    intensity = 255 - ((color.R + color.G + color.B) / 3);
                }
                else
                    intensity = 0;

                if (intensity >= 128)
                    currentValue |= bit;
                bit = bit >> 1;
                if (bit == 0)
                {
                    DataString.Append(currentValue.ToString("X2"));
                    bit = 128;
                    currentValue = 0;
                }
            }//x
        }//y
        DataString.Append("\r\n");

        return DataString.ToString();
    }

After that failed, I found the CPCL programming guide for Zebra printers and followed the example on page 95 to print the little tile image. However, this did the same thing as the signature. Once that failed, I found that I needed to run the command: ! U1 setvar "device.languages" "zpl" before doing any EG commands; so I went ahead and did this but things took a bad turn here which end up forcing me to fully reset the printer and/or cleanboot the handheld because it causes a COM exception that crashes COM6 and the printer.

I have exhausted most if not all of the resources that I can think of and none of them have worked.

Does anyone have any other ideas or examples that could help me get this working?

Thanks


Solution

  • I found another CPCL programmers guide and it has this simple (test) example:

    ! 0 200 200 210 1
    EG 2 16 90 45 F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
    F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
    FORM
    PRINT
    

    This should print a small checker board pattern.

    The next example prints a PCX graphic:

    PCX Commands
    The PCX command gives a user the ability to send “.PCX” graphics formatted images to the printer. The
    .PCX image MUST be encoded as a black and white image.
    Format:
    {command} {x} {y}
    {data}
    where:
    {command}: PCX
    {x}: X-coordinate of the top-left corner.
    {y}: Y-coordinate of the top-left corner.
    {data}: PCX image data.
    

    Example:

    ! 0 200 200 500 1
    PCX 0 30
    <binary black and white pcx data stream>
    FORM
    PRINT
    

    Example using a file (loaded previously the printers file system)

    ! 0 200 200 500 1
    PCX 0 30 !<IMAGE.PCX
    FORM
    PRINT
    

    If the printer has been switched to line printer mode, the command

    ! U1 PCX {x coordinate} {y coordinate} !< {filename.pcx}
    

    for example

    ! U1 PCX 0 30 !< IMAGE.PCX
    

    can be used to print monochrome PCX from file system.

    Remeber that .NET is UTF-8 and so all commands and data has to be converted to ASCII before sending over a COM port. So do something like this:

            Encoding ansi = Encoding.GetEncoding(1252);
            byte[] buf = ansi.GetBytes(DataString);
            System.IO.Ports.SerialPort sp = new System.IO.Ports.SerialPort("COM1:");
            sp.Write(buf, 0, buf.Length);
    

    for the PCX data just use the byte stream for the byte[] buffer.