移动端打印的实现方式参考
上一篇:DCloud UniAPP Android 蓝牙连接ESCPOS打印机
本片来实现 上一篇中 打印图片中 的 img (图片点阵灰度数据)
var img=XXXXX //图片点阵灰度数据
printer.printImg(img);
对应的实现方式使用C#实现,draw2PxPoint方法将指定图片转成ESCPOS打印机可以识别的图片打印指令
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace CommonPrint.ImageUtil
{
public class ImageHelper
{
public static Image UrlToImage(string url)
{
WebClient mywebclient = new WebClient();
byte[] Bytes = mywebclient.DownloadData(url);
using (MemoryStream ms = new MemoryStream(Bytes))
{
Image outputImg = Image.FromStream(ms);
return outputImg;
}
}
public static int[] draw2PxPoint(Bitmap bmp)
{
//第一步调整图片高宽 到目标大小 商米设备最大支持124~125个点位的图片打印
int newWidth = 120;
int newHeight = 120;
bmp = ZoomImage(bmp, newWidth, newHeight);
List<int> data = new List<int>();
//设置行距为0的指令
data.Add(0x1B);
data.Add(0x33);
data.Add(0x00);
int temp = 0;
int turn = 0;
// 逐行打印
for (int j = 0; j < bmp.Height / 12f; j++)
{
//打印图片的指令
data.Add(0x1B);
data.Add(0x2A);
data.Add(32);//单精度
data.Add((byte)(bmp.Width % 256)); //nL 因为一个Byte最大255 表示大于255的数据需要用2位来处理( nL+nH×256)
data.Add((byte)(bmp.Width / 256)); //nH
//对于每一行,逐列打印
for (int i = 0; i < bmp.Width; i++)
{
每一列24个像素点,分为3个字节存储
for (int m = 0; m < 3; m++)
{
StringBuilder sb = new StringBuilder();
//一次性读4个点 单精度 需要放大Y轴方向的数据 所以取一个点占2位
for (int n = 0; n < 4; n++)
{
var p = px2Byte(i, j * 12 + m * 4 + n, bmp);
//每个点Y轴方向重复一次 占2位
sb.Append(p);
sb.Append(p);
}
//Java上 byte 是-128 ~ 127 255=-1
int res = Convert.ToInt32(sb.ToString().Substring(1, 7), 2);
if (res > 127) {
res = res - 256;
}
data.Add((byte)res);
}
}
data.Add(10);//换行
}
bmp.Dispose();
return data.ToArray();
}
public static byte px2Byte(int x, int y, Bitmap bmp)
{
if (x < bmp.Width && y < bmp.Height)
{
byte b;
Color color = bmp.GetPixel(x, y);
int gray = (int)(0.29900 * color.R + 0.58700 * color.G + 0.11400 * color.B);
if (gray > 128)
{
b = 0;
}
else
{
b = 1;
}
return b;
}
return 0;
}
/// <summary>
/// 等比例缩放图片
/// </summary>
/// <param name="bitmap">图片</param>
/// <param name="destHeight">高度</param>
/// <param name="destWidth">宽度</param>
/// <returns></returns>
private static Bitmap ZoomImage(Bitmap bitmap, int destHeight, int destWidth)
{
try
{
System.Drawing.Image sourImage = bitmap;
int width = 0, height = 0;
//按比例缩放
int sourWidth = sourImage.Width;
int sourHeight = sourImage.Height;
if (sourHeight > destHeight || sourWidth > destWidth)
{
if ((sourWidth * destHeight) > (sourHeight * destWidth))
{
width = destWidth;
height = (destWidth * sourHeight) / sourWidth;
}
else
{
height = destHeight;
width = (sourWidth * destHeight) / sourHeight;
}
}
else
{
width = sourWidth;
height = sourHeight;
}
Bitmap destBitmap = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage(destBitmap);
g.Clear(Color.Transparent);
//设置画布的描绘质量
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(sourImage, new Rectangle((destWidth - width) / 2, (destHeight - height) / 2, width, height), 0, 0, sourImage.Width, sourImage.Height, GraphicsUnit.Pixel);
g.Dispose();
//设置压缩质量
System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
long[] quality = new long[1];
quality[0] = 100;
System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[0] = encoderParam;
sourImage.Dispose();
return destBitmap;
}
catch
{
return bitmap;
}
}
}
}