I want to print a bitmap directly to a network printer using a socket.
To do this I use PCL codes to set the printer in the right mode and
print the image.
Note that this code is used on the Compact Framework, so there is no
PrintDocument or even a driver I can use.
try
{
// Connect to printer.
s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.IP);
IPAddress addr = IPAddress.Parse("10.0.0.18");
IPEndPoint ipep = new IPEndPoint(addr, 9100);
s.Connect(ipep);
Bitmap bmp = new Bitmap(appPath + "images\\Chart_PHT.gif");
System.IO.MemoryStream msBitmap = new System.IO.MemoryStream();
bmp.Save(msBitmap, System.Drawing.Imaging.ImageFormat.Gif);
System.Drawing.Imaging.BitmapData bmpd = bmp.LockBits(new Rectangle(0,
0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb) ;
IntPtr ptr = bmpd.Scan0;
// Declare an array to hold the bytes of the bitmap.
// This code is specific to a bitmap with 24 bits per pixels.
int bytes = bmp.Width * bmp.Height * 3;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpd);
// reset printer
byte[] byteReset = new byte[] { 027, 069 };
s.Send(byteReset, 0, 2, SocketFlags.None);
// set resolution
byte[] byteRes = new byte[] { 027, 042, 116, 051, 048, 048, 082 }; //
300 DPI
s.Send(byteRes, 0, 7, SocketFlags.None);
// start raster graphics
byte[] byteStart = new byte[] { 027, 042, 114, 049, 065 };
s.Send(byteStart, 0, 5, SocketFlags.None);
// set compression
byte[] byteComp = new byte[] { 027, 042, 098, 048, 077 }; //
uncompressed
s.Send(byteComp, 0, 5, SocketFlags.None);
// send graphics
for (int i = 0; i < (rgbValues.Length); i += (bmp.Width * 3))
{
byte[] byteSend1 = new byte[] { 027, 042, 098 };
byte[] byteSend2 = BitConverter.GetBytes(bmp.Width * 3);
byte[] byteSend3 = null;
if ((i + (bmp.Width * 3)) < rgbValues.Length)
byteSend3 = new byte[] { 086 };
else
byteSend3 = new byte[] { 087 }; // for last row
byte[] byteSendAll = new byte[byteSend1.Length + byteSend2.Length +
byteSend3.Length + (bmp.Width * 3)];
Buffer.BlockCopy(byteSend1, 0, byteSendAll, 0, byteSend1.Length);
Buffer.BlockCopy(byteSend2, 0, byteSendAll, byteSend1.Length,
byteSend2.Length);
Buffer.BlockCopy(byteSend3, 0, byteSendAll, byteSend1.Length +
byteSend2.Length, byteSend3.Length);
Buffer.BlockCopy(rgbValues, i, byteSendAll, byteSend1.Length +
byteSend2.Length + byteSend3.Length, bmp.Width * 3);
s.Send(byteSendAll, SocketFlags.None);
}
// end raster graphics
byte[] byteEnd = new byte[] { 027, 042, 114, 098, 067 };
s.Send(byteEnd, 0, 5, SocketFlags.None);
}
finally
{
s.Close();
}
Sending out the PCL codes (arrays starting with 027) works excellent.
But the printing of the actual data does not work yet.
The rgbValues array now has the RGB values of all pixels (so three
bytes used for each pixel). But when I send that straight after the
start printing command it does not print anything on the paper.
I do send it to the open socket line by line as suggested by the
documentation I found, but that didn't help either.
Does anyone have a clue about what format to use to send the bitmap
data to the printer?