Printing to Zebra printer gives faint and blurry images
I wrote a library which creates a bitmap image from some user input. This bitmap is then printed using a zebra printer. The problem I am running into is everything is very faint and blurry on the image printed by the zebra printer but if I print the bitmap to a laser printer it looks perfectly normal. Has anyone run into this before and if so how did they fix it? I have tried nearly everything I can thin开发者_开发百科k of printer settings wise.
Updated with code for how I create the bitmap images.
public static Bitmap GenerateLabel<T>(T obj, XmlDocument template)
{
try
{
int width = Convert.ToInt32(template.SelectSingleNode("/LABELS/@width").Value);
int height = Convert.ToInt32(template.SelectSingleNode("/LABELS/@height").Value);
if (obj == null || height <= 0 || width <= 0)
throw new ArgumentException("Nothing to print");
Bitmap bLabel = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bLabel);
XmlNodeList fieldList = template.SelectNodes("/LABELS/LABEL");
foreach (XmlNode fieldDetails in fieldList)
{
//non important code...
g.DrawImage(bBarCode, field.Left, field.Top);
using (TextBox txtbox = new TextBox())
{
// more non important code...
Rectangle r = new Rectangle(field.Left, field.Top, field.Width, field.Height);
txtbox.DrawToBitmap(bLabel, r);
}
}
return bLabel;
}
catch (Exception ex)
{
throw new Exception("Unable to create bitmap: " + ex.Message);
}
}
The Zebra print driver is dithering your output. To create a perfect image for Zebra printing, you'll need to create an image at 203 DPI and 2-color black and white (1-bit).
This is a universal 'feature' among all zebra printers, the drivers compress the images using a lossy technique before transmission to the printer itself, there is no workaround as far as I can tell.
I ended up using a third party library called Thermal SDK which allowed me to draw/save my bitmap and then send it to the zebra printer in the 'special' format it needed. It works for single labels but if you wanted to do many at a time it would be pretty inefficient since you have to save each label to a file before you can print it.
The printer requires a 1 bpp monochrome image. And there is no perfect algorithm for converting a color or grayscale image to monochrome. Such algorithms may or may not produce a good result depending on the image. So the best way is to prepare an image to be monochrome from the beginning, like Mike Ransom stated above. But if it has to be done programmatically, the initial color image should use black and white colors only (so that the conversion produces a good result) and then you can use an algorithm like this (source link here):
public static Bitmap BitmapTo1Bpp(Bitmap img)
{
int w = img.Width;
int h = img.Height;
Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed);
BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
for (int y = 0; y < h; y++)
{
byte[] scan = new byte[(w + 7) / 8];
for (int x = 0; x < w; x++)
{
Color c = img.GetPixel(x, y);
if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
}
Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
}
bmp.UnlockBits(data);
return bmp;
}
once place to look at is the driver settings, what is the dpi on the printer, there are many settings that can be causing the effect not just the lossy technique.
we've sent many bitmap images to zebras and intermec thermals it should work
Answer is easy. Zebra printers only prints Black and White, so before you send the image to the printer, convert it to black and white.
I'm not a C# coder but VB code looks similar so I hope his helps:
''' <summary>
''' Converts an image to Black and White
''' </summary>
''' <param name="image">Image to convert</param>
''' <param name="Mode">Convertion mode</param>
''' <param name="tolerance">Tolerancia del colores</param>
''' <returns>Converts an image to Black an white</returns>
''' <remarks></remarks>
Public Function PureBW(ByVal image As System.Drawing.Bitmap, Optional ByVal Mode As BWMode = BWMode.By_Lightness, Optional ByVal tolerance As Single = 0) As System.Drawing.Bitmap
Dim x As Integer
Dim y As Integer
If tolerance > 1 Or tolerance < -1 Then
Throw New ArgumentOutOfRangeException
Exit Function
End If
For x = 0 To image.Width - 1 Step 1
For y = 0 To image.Height - 1 Step 1
Dim clr As Color = image.GetPixel(x, y)
If Mode = BWMode.By_RGB_Value Then
If (CInt(clr.R) + CInt(clr.G) + CInt(clr.B)) > 383 - (tolerance * 383) Then
image.SetPixel(x, y, Color.White)
Else
image.SetPixel(x, y, Color.Black)
End If
Else
If clr.GetBrightness > 0.5 - (tolerance / 2) Then
image.SetPixel(x, y, Color.White)
Else
image.SetPixel(x, y, Color.Black)
End If
End If
Next
Next
Return image
End Function
精彩评论