delphi 连接网口打印机 通过图像打印二维码 出现黑块 的解决之路


procedure draw2PxPoint(userid: string; bmp: TBitmap; isNet: Boolean; align: Integer);
var
    PicNamearray: array[0..20] of Byte;
    Send: string;
    size: Integer;
    data: array of Byte;
    k, i, j, m, n, index: Integer;
    canvas: TCanvas;
    b: Byte;
    temp: string;
    color: TColor;
    currentSum: Integer;
begin
    try
        //可以将图片压缩成指定大小,打印出来就是多大
        size := bmp.Width * bmp.Height div 8 + 100;
        canvas := bmp.Canvas;
        SetLength(data, size);
        //设置行距为0的指令
        k := 0;
        data[k] := $1B;
        k := k + 1;
        data[k] := $33;
        k := k + 1;
        data[k] := $00;
        k := k + 1;
        //居中打印
        data[k] := $1B;
        k := k + 1;
        data[k] := $61;
        k := k + 1;
        case align of
            0: data[k] := $00;
            1: data[k] := $01;
            2: data[k] := $02;
        end;

        k := k + 1;
        //逐行打印
        for j := 0 to (bmp.Height div 24 - 1) do
        begin
            data[k] := $1B;
            k := k + 1;
            data[k] := $2A;
            k := k + 1;
            data[k] := 33;
            k := k + 1;
            data[k] := bmp.Width mod 256;
            k := k + 1;
            data[k] := bmp.Width div 256;
            k := k + 1;
            //对于每一行,逐列打印
            for i := 0 to bmp.Width - 1 do
            begin
                for m := 0 to 2 do
                begin
                    currentSum := j * 24 + m * 8;
                    color := canvas.Pixels[i, currentSum];
                    if color = clWhite then
                        data[k] := 0
                    else
                        data[k] := 255;
                    k := k + 1;
                end;
            end;
            data[k] := 10; //换行
            k := k + 1;
        end;

        //打印命令在这里 上面是准备数据
        for index := 0 to Length(data) - 1 do
        begin
            temp := temp + AnsiChar(strtoint('$' + IntToHex(data[index], 2)))
        end;
        
        Send := AnsiChar($1D) + AnsiChar($21) + AnsiChar($11);
        Move(Send[1], PicNamearray, Length(Send));
        frmMain.IdTCPClient_xy.Socket.Send(PicNamearray, Length(Send));
        frmMain.IdTCPClient_xy.Writeln(temp);
    finally
        bmp.FreeImage;
    end;
end;

  if color = clWhite then
                        data[k] := 0
                    else
                        data[k] := 255;

出现这种黑块就是因为这一堆的255,我初步判断是底层封装的这个方法不可靠。

解决方案一:

color := GetPixel(canvas.Handle,i,currentSum); //WindowsAPI

用这行代码替代 color := canvas.Pixels[i, currentSum];  

这两个一个是WindowsAPI提供的方法,一个是bitmap提供的方法,前者获取成功的准确度明显高于后者。

解决方案二:

Delphi提供了一种扫描线ScanLine方法是对图像的一行进行扫描,获取本行中各像素的内存地址。众所周知,内存操作肯定会比常规的像素点赋值速度快很多,所以将大大提高图像的处理速度。

procedure draw2PxPoint(userid: string; bmp: TBitmap; isNet: Boolean; align: Integer);
var
    PicNamearray: array[0..20] of Byte;
    Send: string;
    size: Integer;
    data: array of Byte;
    k, i, j, m, n, index: Integer;
    canvas: TCanvas;
    b: Byte;
    temp: string;
    color: TColor;
    currentSum: Integer;
    imagePath:String;
    Red,Green,Blue:Byte;

    PColor:array of PByteArray;//像素数组
    height,hindex,Gray:Integer;
begin
    try
        //可以将图片压缩成指定大小,打印出来就是多大
        size := bmp.Width * bmp.Height div 8 + 100;
        canvas := bmp.Canvas;
        SetLength(data, size);
        height:= bmp.Height;
        SetLength(PColor,height);
        for hindex:=0 to height-1 do
        begin
         PColor[hindex]:=bmp.ScanLine[hindex];//将图片所有像素值存入P
        end;

        //设置行距为0的指令
        k := 0;
        data[k] := $1B;
        k := k + 1;
        data[k] := $33;//选择24点双密度打印,分辨率达到200DPI。
        k := k + 1;
        data[k] := $00;
        k := k + 1;
        //居中打印
        data[k] := $1B;
        k := k + 1;
        data[k] := $61;
        k := k + 1;
        case align of
            0: data[k] := $00;
            1: data[k] := $01;
            2: data[k] := $02;
        end;

        k := k + 1;
        //逐行打印
        for j := 0 to (bmp.Height div 24 - 1) do
        begin
            data[k] := $1B;
            k := k + 1;
            data[k] := $2A;
            k := k + 1;
            data[k] := 33;
            k := k + 1;
            data[k] := bmp.Width mod 256;
            k := k + 1;
            data[k] := bmp.Width div 256;
            k := k + 1;
            for i := 0 to bmp.Width - 1 do
            begin
              for m := 0 to 2 do
              begin
                currentSum := j * 24 + m * 8;
                //颜色值这个我确实不太懂,但是我发现Blue一直为255,而Green和Red  会在黑色和白色时分别为 0 和 255
              //  Blue:= PColor[i][currentSum];
              //  Green:= PColor[i][currentSum*3+1];
                Red := PColor[i][currentSum*3+2];
               // Gray:= Round(Blue * 0.3 +Green * 0.59 +Red * 0.11);
                if Red = 0 then
               // if Gray<128 then
                  data[k] := 255
                else
                  data[k] := 0;
                k := k + 1;
              end;
            end;
            data[k] := 10; //换行
            k := k + 1;
        end;

        //打印命令在这里 上面是准备数据
        for index := 0 to Length(data) - 1 do
        begin
            temp := temp + AnsiChar(strtoint('$' + IntToHex(data[index], 2)))
        end;
        if isNet then
            userQRData.Put(userid, temp);
        //QRBitmapTemp:=temp;
        Send := AnsiChar($1D) + AnsiChar($21) + AnsiChar($11);
        Move(Send[1], PicNamearray, Length(Send));
        frmMain.IdTCPClient_xy.Socket.Send(PicNamearray, Length(Send));
        frmMain.IdTCPClient_xy.Writeln(temp);
    finally
        bmp.FreeImage;
    end;
end;

至此,问题完全解决。

参考网址:

用Delphi直接获取bmp图片的像素 - 为人民服务 - 博客园

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值