分享

用delphi控制小票打印机打印图片

 delphi_笔记 2018-07-24
/字节数组
标签:

it

分类: delphi

用delphi控制小票打印机打印图片

用delphi控制小票打印机打印图片

unit PosPrintBmp;

{***********************************************************************}

{ 单元名称:PosPrintBmp     小票打印机打印图片的类                      }

{                                                                       }

{ 创建人:李红雷                                                        }

{ 日期:2012.2                                                          }

{ 修改人:                                                              }

{ 日期:                                                                }

{ 功能:GetDocument函数 得到图片的字节数组                              }

{       属性ByteLen 得到字节数组的长度                                  }

{ 用法: PosPrintBmp := TPosPrintBmp.Create(FPicName);                   }

{    try                                                                }

{      PrintPic := PosPrintBmp.GetDocument;                             }

{      gLen := PosPrintBmp.ByteLen;                                     }

{      WritePrinter(hprinter, @PrintPic, gLen, N);                      }

{    finally                                                            }

{      PosPrintBmp.Free;                                                }

{    end;                                                               }

{***********************************************************************}

interface

uses

  Windows, SysUtils, Classes, Graphics, jpeg;


const

  Nul: Char = #0;

  FormFeed: Char = #12;

  Escape: Char = #27;

  Newline: Char = #10;

  GroupSeparator: Char = #29;

  HorizontalTab: Char = #9;

  CarriageReturn: Char = #13;

  Cancel: Char = #24;

  DataLinkEscape: Char = #16;

  EndOfTransmission: Char = #4;

  FileSeparator: Char = #28;

  Sat: Char = #64; //@

  Sv: Char = #86;  //V

  S66: Char = #66;

  S3: Char = #51;

  Sx: Char = #42;  //*

  S24: Char = #24;

  S33: Char = #33;

  S30: Char = #30;

  S3_1: Char = #3;


type

  TData = packed record

    Dots: array of Boolean;

    Height, Width: Integer;

  end;


  TPosPrintBmp = class(TObject)

  private

    FLen: Integer;

    FPicName: string;

    function GetBitmapData(PicName: string): TData;

    procedure RenderLogo(out fms: TMemoryStream);

  public

    constructor Create(const AFileName: string);

    function GetDocument: TByteArray;     //得到图片的字节数组

  published

    property ByteLen: Integer read FLen;  //字节数组的长度

  end;


implementation


constructor TPosPrintBmp.Create(const AFileName: string);

begin

  inherited Create;

  FPicName := AFileName;

end;


function TPosPrintBmp.GetBitmapData(PicName: string): TData;

const

  threshold: Integer = 127;

var

  Bmp: TBitmap;

  index, dimensions, x, y, luminance: Integer;

  dots: array of Boolean;

  AData: TData;

  RGB: TColor;

  RC, GC, BC: Byte;

  jpeg: TJPEGImage;

begin

  index := 0;

  Bmp := TBitmap.Create;

  try

    if UpperCase(ExtractFileExt(PicName)) = '.JPG' then

    begin

      jpeg := TJPEGImage.Create;

      try

        jpeg.LoadFromFile(PicName);

        Bmp.Assign(jpeg);

      finally

        jpeg.Free;

      end

    end else

      Bmp.LoadFromFile(PicName);

    dimensions := Bmp.Width * Bmp.Height;

    SetLength(dots, dimensions);

    for y := 0 to Bmp.Height - 1 do

    begin

      for x := 0 to Bmp.Width - 1 do

      begin

        RGB := Bmp.Canvas.Pixels[x, y];

        RC := RGB and $FF;

        GC := RGB and $FF00 shr 8;

        BC := RGB and $FF0000 shr 16;

        luminance := Round(RC * 0.3 + GC * 0.59 + BC * 0.11);

        dots[index] := (luminance < threshold);

        Inc(index);

      end;  

    end;

  finally

    AData.Height := Bmp.Height;

    AData.Width := Bmp.Width;

    SetLength(AData.Dots, Length(dots));

    Move(dots[0], AData.Dots[0], Length(dots));

    Bmp.Free;

  end;

  Result := AData;

end;


procedure TPosPrintBmp.RenderLogo(out fms: TMemoryStream);

var

  Data: TData;

  FDots: array of Boolean;

  offset, I, K, b, x, y, tmpint, M: Integer;

  v: Boolean;

  slice: Byte;

  FWidth: array of Byte;

begin

  Data := GetBitmapData(FPicName);

  SetLength(FDots, Length(Data.Dots));

  Move(Data.Dots[0], FDots[0], Length(Data.Dots));

  SetLength(FWidth, 4);

  FWidth[0] := Data.Width and $FF;

  FWidth[1] := Data.Width and $FF00 shr 8;

  FWidth[2] := Data.Width and $FF0000 shr 16;

  FWidth[3] := Data.Width and $FF000000 shr 24;

  

  fms.Write(Newline, 1);


  fms.Write(Escape, 1);

  fms.Write(s3, 1);

  fms.Write(S24, 1);


  offset := 0;

  OutputDebugString(PChar('offset=' + IntToStr(offset)));

  while (offset < Data.Height) do

  begin

    fms.Write(Escape, 1);

    fms.Write(Sx, 1);         // bit-image mode

    fms.Write(S33, 1);        // 24-dot double-density

    fms.Write(FWidth[0], 1);  // width low byte

    fms.Write(FWidth[1], 1);  // width high byte

    for x := 0 to data.Width - 1 do

    begin

      for K := 0 to 2 do

      begin

        slice := 0;

        for b := 0 to 7 do

        begin

          y := (((offset div 8) + k) * 8) + b;

          i := (y * data.Width) + x;

          v := False;

          if (I < Length(Data.Dots)) then

            v := FDots[I];

          tmpint := 7 - b;

          if v then

            M := 1 shl tmpint

          else

            M := 0 shl tmpint;

          slice := slice or M;

        end;

        fms.Write(slice, 1);

      end;

    end;

    Inc(offset, 24);

    if offset < Data.Height then // 去掉结束空行

      fms.Write(Newline, 1);

  end;

  // Restore the line spacing to the default of 30 dots.

  fms.Write(Escape, 1);

  fms.Write(S3, 1);

  fms.Write(S30, 1);

end;


function TPosPrintBmp.GetDocument: TByteArray;

var

  ms: TMemoryStream;

  TmpBA: TByteArray;

begin

  ms := TMemoryStream.Create;

  try

    ms.Write(Escape, 1);

    ms.Write(Sat, 1);


    RenderLogo(ms);


    //ms.Write(GroupSeparator, 1);

    //ms.Write(Sv, 1);

    //ms.Write(S66, 1);

    //ms.Write(S3_1, 1);

    ms.Write(Newline, 1);


    ms.Position := 0;

    FLen := ms.Size;

    ms.ReadBuffer(TmpBA[0], ms.Size);

  finally

    ms.Free;

  end;

  Result := TmpBA;

end;


end.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多