1

I am using C# and write code for print contents for the Thermal ticket printer.

There are codes that people use for image print, and it indeed prints images, but something goes wrong. This is my code for image print class, it is widely using open source (I googled and found it, and people successfully implement this code to theirs without problem).

public static class ImagePrint
{
    /// <summary>
    /// Image convert to Byte Array
    /// </summary>
    /// <param name="LogoPath">Image Path</param>
    /// <param name="printWidth">Image print Horizontal Length</param>
    /// <returns></returns>
    public static byte[] GetLogo(string LogoPath, int printWidth)
    {
        List<byte> byteList = new List<byte>();
        if (!File.Exists(LogoPath))
            return null;
        BitmapData data = GetBitmapData(LogoPath, printWidth);
        BitArray dots = data.Dots;
        byte[] width = BitConverter.GetBytes(data.Width);

        int offset = 0;
        // Initialize Printer
        byteList.Add(Convert.ToByte(Convert.ToChar(0x1B)));
        byteList.Add(Convert.ToByte('@'));

        // Line Spacing Adjust (24/180 inch)
        byteList.Add(Convert.ToByte(Convert.ToChar(0x1B)));
        byteList.Add(Convert.ToByte('3'));
        byteList.Add((byte)24);
        while (offset < data.Height)
        {
            byteList.Add(Convert.ToByte(Convert.ToChar(0x1B)));
            byteList.Add(Convert.ToByte('*'));
            byteList.Add((byte)33);
            byteList.Add(width[0]);
            byteList.Add(width[1]);

            for (int x = 0; x < data.Width; ++x)
            {
                for (int k = 0; k < 3; ++k)
                {
                    byte slice = 0;
                    for (int b = 0; b < 8; ++b)
                    {
                        int y = (((offset / 8) + k) * 8) + b;
                        int i = (y * data.Width) + x;

                        bool v = false;
                        if (i < dots.Length)
                            v = dots[i];

                        slice |= (byte)((v ? 1 : 0) << (7 - b));
                    }
                    byteList.Add(slice);
                }
            }
            offset += 24;
            byteList.Add(Convert.ToByte(0x0A));
        }

        // Return to normal line spacing (30/160 inch)
        byteList.Add(Convert.ToByte(0x1B));
        byteList.Add(Convert.ToByte('3'));
        byteList.Add((byte)30);
        return byteList.ToArray();
    }

    private static BitmapData GetBitmapData(string bmpFileName, int width)
    {
        using (var bitmap = (Bitmap)Bitmap.FromFile(bmpFileName))
        {
            var threshold = 127;
            var index = 0;
            double multiplier = width; // 이미지 width조정
            double scale = (double)(multiplier / (double)bitmap.Width);
            int xheight = (int)(bitmap.Height * scale);
            int xwidth = (int)(bitmap.Width * scale);
            var dimensions = xwidth * xheight;
            var dots = new BitArray(dimensions);

            for (var y = 0; y < xheight; y++)
            {
                for (var x = 0; x < xwidth; x++)
                {
                    var _x = (int)(x / scale);
                    var _y = (int)(y / scale);
                    var color = bitmap.GetPixel(_x, _y);
                    var luminance = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
                    dots[index] = (luminance < threshold);
                    index++;
                }
            }

            return new BitmapData()
            {
                Dots = dots,
                Height = (int)(bitmap.Height * scale),
                Width = (int)(bitmap.Width * scale)
            };
        }
    }

    private class BitmapData
    {
        public BitArray Dots
        {
            get;
            set;
        }

        public int Height
        {
            get;
            set;
        }

        public int Width
        {
            get;
            set;
        }
    }
}

And I use this code like this on my code for image print:

string Image_File_Path = @"D:\TEST\TESTImage.bmp";
int Image_Size_I_Want = 100;
byte[] img = ImagePrint.GetLogo(Image_File_Path, Image_Size_I_Want);
port.Write(img, 0, img.Length);

You can see the result in the attached picture.
There are white space lines on the image.
This class automatically adds a line spacing command, but it seems does not work.
Please suggest any solution.

Bad Image Printing

Yun
  • 3,056
  • 6
  • 9
  • 28
  • Most thermal printers should have commands for printing images that are easier and more reasonable than this, but what is the exact vendor name and model number of the printer you are trying to use? Also add information about what printer library you are trying to use. – kunif Oct 05 '21 at 11:10
  • Simply put, it probably doesn't support or has disabled line spacing. For example, if you send an initialization command, you may need a delay before sending the next command. Try setting the line spacing to a large value such as 60 or 100 instead of 24 in the current source code and see if it changes. So if the line spacing changes, it doesn't support the value 24. – kunif Oct 05 '21 at 12:20
  • Printer manufacturer is from China, not that famous one but build quality is good. And yes, I have strong doubt about line spacing feature, is disabled or simply does not work. Maybe it uses different command instead of ESP/P compatible. And if I use SDK which manufacture provides, it should be easy and simple but I normally don't want add more third party DLLs to my project.... – Stephen W. Park Oct 06 '21 at 00:13
  • It's better to add this info to the question with Edit. – HoRn Oct 11 '21 at 07:28

1 Answers1

0

Using 'mike42/escpos-php' package in laravel


use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;

 $tux = EscposImage::load(public_path()."\assets\img\path-to-file.jpg");
 $printer->setJustification(Printer::JUSTIFY_CENTER);
 $printer->bitImage($tux, 0);
 $printer -> setJustification();
Vinay A N
  • 11
  • 1