/// <summary> /// Returns an array of bytes to be sent to the /dev/usb/lp0 device. /// </summary> /// <param name="raster"></param> /// <returns></returns> public byte[] RasterToPrintCommands(BWImage raster) { int width = raster.size.Width; int height = raster.size.Height; int dotsPerLine = Math.Min(width, pageWidth); int bytesPerLine = dotsPerLine / 8; if (dotsPerLine != bytesPerLine * 8) { throw new InvalidDataException("raster width should be a multiple of 8"); } List <byte> output = new List <byte>(bytesPerLine * height + 1); IEnumerable <bool> rasterData; int byteCount = raster.data.Length / 8; if (raster.data.Length % 8 != 0) { int needed = 8 - (raster.data.Length % 8); var rasterDataList = raster.data.ToList(); for (int i = 0; i < needed; i++) { rasterDataList.Add(false); } rasterData = rasterDataList.AsEnumerable().Reverse(); byteCount++; } else { rasterData = raster.data.Reverse(); } BitArray compactedBits = new BitArray(rasterData.ToArray()); byte[] compactedByteBufferArray = new byte[byteCount]; compactedBits.CopyTo(compactedByteBufferArray, 0); var compactedByteBuffer = compactedByteBufferArray.Reverse(); output.AddRange(new byte[] { 0x1b, 0x40 }); for (int y = 0; y < height; y += 24) { int sliceHeight = Math.Min(24, height - y); output.AddRange(new byte[] { 0x1d, 0x76, 0x30, 0x00 }); output.Add((byte)(bytesPerLine % 256)); output.Add((byte)(bytesPerLine / 256)); output.Add((byte)(sliceHeight % 256)); output.Add((byte)(sliceHeight / 256)); output.AddRange(compactedByteBuffer.Skip(y * bytesPerLine).Take(bytesPerLine * sliceHeight)); output.AddRange(new byte[] { 0x1b, 0x4a, 0x15 }); } output.AddRange(new byte[] { 0x1b, 0x40 }); return(output.ToArray()); }
/// <summary> /// Returns an array of bytes to be sent to the /dev/usb/lp0 device. Will rotate and scale the image before dithering. /// </summary> /// <param name="inputImage"></param> /// <param name="ditherer">The ditherer to be used. Use new BurkesDitherer() if unsure.</param> /// <param name="rotateForLargerPrint">If true, the image will be rotated 90 degrees if that would increase the printed size.</param> /// <returns></returns> public byte[] ImageToPrintCommands(Bitmap inputImage, IDitherer ditherer, bool rotateForLargerPrint = true) { var resized = ScaleToFitPage(inputImage, rotateForLargerPrint); BWImage result = ditherer.GetBWImage(resized); byte[] printCommands = RasterToPrintCommands(result); return(printCommands); }
public BWImage GetBWImage(Bitmap image) { size = image.Size; size.Width = (size.Width / 8) * 8; BWImage output = new BWImage(size); data = new byte[size.Width, size.Height]; for (int y = 0; y < size.Height; y++) { for (int x = 0; x < size.Width; x++) { Color c = image.GetPixel(x, y); float pixelValue = (c.R * 2126 + c.G * 7152 + c.B * 0722) / 2550000f; float invValue = 1f - pixelValue; data[x, y] = (byte)((1 - invValue * invValue) * 255); } } for (int y = 0; y < size.Height; y++) { for (int x = 0; x < size.Width; x++) { byte value = data[x, y]; bool thresholded = value < threshold; int error = thresholded ? value : value - 255; int shifty = 0; for (int shiftx = 1; shifty < 2; shiftx++) { int newx = x + shiftx; if (newx >= 0 && newx < size.Width) { int newy = y + shifty; if (newy < size.Height) { data[newx, newy] = ClipToByte(data[newx, newy] + ((BurkesDistribution[shiftx + 5 * shifty] * error) >> 5)); } } if (shiftx == 2) { shiftx = -3; shifty++; } } output.data[x + size.Width * y] = thresholded; } } return(output); }