I'm directly printing my receipt to the POS printer via serial port in the following way,
SerialPort port = new SerialPort("com6", 9100, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Some Text");
port.Close();
My question is how I'm going to print a Bitmap image using the above method? Any help would be grateful.
I have not decided to go with Microsoft POS for.net, because it is slow and takes time to initialize the printer, where clients doesn't like to wait.
Thanks.
This should get you a string from bitmap that you would be able to send to printer:
public string GetLogo()
{
string logo = "";
if (!File.Exists(@"C:\bitmap.bmp"))
return null;
BitmapData data = GetBitmapData(@"C:\bitmap.bmp");
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 GetBitmapData(string bmpFileName)
{
using (var bitmap = (Bitmap)Bitmap.FromFile(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)
};
}
}
public class BitmapData
{
public BitArray Dots
{
get;
set;
}
public int Height
{
get;
set;
}
public int Width
{
get;
set;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With