0

我想将阿拉伯文本作为位图发送到 POS 打印机,因为我无法将阿拉伯文字直接打印到打印机。我使用下面的代码将文本转换为 Bitmap :

Convert_ValueToImage("كيكه", "Simplified Arabic Fixed", 12)

public static Bitmap Convert_ValueToImage(string ValueText, string Fontname, int Fontsize)
    {
        //creating bitmap image
        Bitmap ValueBitmap = new Bitmap(1, 1);
        //FromImage method creates a new Graphics from the specified Image.
        Graphics Graphics = Graphics.FromImage(ValueBitmap);

        // Create the Font object for the image text drawing.
        Font Font = new Font(Fontname, Fontsize);

        // Instantiating object of Bitmap image again with the correct size for the text and font.
        SizeF stringSize = Graphics.MeasureString(ValueText, Font);
        ValueBitmap = new Bitmap(ValueBitmap, (int)stringSize.Width, (int)stringSize.Height);
        Graphics = Graphics.FromImage(ValueBitmap);

        //Draw Specified text with specified format
        Graphics.DrawString(ValueText, Font, Brushes.Black, 0, 0);

        Font.Dispose();
        Graphics.Flush();
        Graphics.Dispose();

        return ValueBitmap; //return Bitmap Image
    }

当我将它分配给图片框时,它可以工作。现在我想将它发送到打印机。我使用以下方法将位图图像转换为字符串,并将图像模式添加到字符串:

public string GetArabic(Bitmap ArabicText)
    {
        string logo = ""; 
         BitmapData data = GetArabicBitmapData(ArabicText);
         BitArray dots = data.Dots;
        byte[] width = BitConverter.GetBytes(data.Width);

        int offset = 0;
        MemoryStream stream = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(stream);

        bw.Write((char)0x1B);
        bw.Write('@');

        bw.Write((char)0x1B);
        bw.Write('3');
        bw.Write((byte)24);

        while (offset < data.Height)
        {
            bw.Write((char)0x1B);
            bw.Write('*');         // bit-image mode
            bw.Write((byte)33);    // 24-dot double-density
            bw.Write(width[0]);  // width low byte
            bw.Write(width[1]);  // width high byte

            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;
                        // Calculate the location of the pixel we want in the bit array.
                        // It'll be at (y * width) + x.
                        int i = (y * data.Width) + x;

                        // If the image is shorter than 24 dots, pad with zero.
                        bool v = false;
                        if (i < dots.Length)
                        {
                            v = dots[i];
                        }
                        slice |= (byte)((v ? 1 : 0) << (7 - b));
                    }

                    bw.Write(slice);
                }
            }
            offset += 24;
            bw.Write((char)0x0A);
        }
        // Restore the line spacing to the default of 30 dots.
        bw.Write((char)0x1B);
        bw.Write('3');
        bw.Write((byte)30);

        bw.Flush();
        byte[] bytes = stream.ToArray();
        return logo + Encoding.Default.GetString(bytes);
    }

 public BitmapData GetArabicBitmapData(Bitmap bmpFileName)
    {

        using (var bitmap =  bmpFileName )
        {
            var threshold = 127;
            var index = 0;
            double multiplier =   570; // this depends on your printer model. for Beiyang you should use 1000
            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)
            };
        }
    }

此代码打印一个黑色矩形。对我有帮助的是,如果我可以打印具有白色背景的文本并且大小与文本大小一样小。

4

0 回答 0