从epson热敏打印机收据上的图像显示白色水平线

时间:2015-12-18 11:40:58

标签: delphi delphi-7 thermal-printer epson

我使用delphi7代码从epson TM-T82打印机打印了位图图像。 我正在向epson打印机发送ESCPOS命令以打印位图图像。 此打印的位图图像包含徽标中的白线。

当我使用具有相同徽标的Epson打印机实用程序时,它打印正常。

有没有人知道如何解决这个问题?

这是我的代码:

unit ssESCPosPrintBitmap;

interface

type
  // *** -------------------------------------------------------------------------
  // *** INTERFACE: IssESCPosPrintBitmap
  // *** -------------------------------------------------------------------------
  IssESCPosPrintBitmap = interface( IInterface )
    ['{3F279585-6D2E-451F-AF97-76F0E07A70DF}']
    function RenderBitmap( const ABitmapFilename: string ): string;
  end;

  function _ESCPosPrintBitmap(): IssESCPosPrintBitmap;

implementation

uses
  Windows,
  Graphics,
  Math;

type
  TRGBTripleArray = ARRAY[Word] of TRGBTriple;
  pRGBTripleArray = ^TRGBTripleArray; // Use a PByteArray for pf8bit color.

  // *** -------------------------------------------------------------------------
  // *** RECORD:  TBitmapData
  // *** -------------------------------------------------------------------------
  TBitmapData = record
    Dots      : array of Boolean;
    Height    : Integer;
    Width     : Integer;
  end;

  // *** -------------------------------------------------------------------------
  // *** CLASS: TssESCPosPrintBitmap
  // *** -------------------------------------------------------------------------
  TssESCPosPrintBitmap = class( TInterfacedObject, IssESCPosPrintBitmap )
    private
      FLumThreshold : Integer;
      FBitmap       : TBitmap;
      FBitmapData   : TBitmapData;
      procedure LoadBitmapData();
    public
      constructor Create();
      destructor Destroy; override;

      function RenderBitmap( const ABitmapFilename: string ): string;
  end;

const
  C_DEFAULT_THRESHOLD = 127;

function _ESCPosPrintBitmap(): IssESCPosPrintBitmap;
begin
  Result := TssESCPosPrintBitmap.Create();
end;


{ TssESCPosPrintBitmap }

{-------------------------------------------------------------------------------
  Procedure: TssESCPosPrintBitmap.Create
  Author:    bvonfintel
  DateTime:  2015.01.06
  Arguments: None
  Result:    None
-------------------------------------------------------------------------------}
constructor TssESCPosPrintBitmap.Create;
begin
  inherited;
  FBitmap       := TBitmap.Create();
  FLumThreshold := C_DEFAULT_THRESHOLD;
end;

procedure TssESCPosPrintBitmap.LoadBitmapData;
var
  LIndex : Integer;
  LX     : Integer;
  LY     : Integer;
  LLine  : pRGBTripleArray;
  LPixel : TRGBTriple;
  LLum   : Integer;
begin
  LIndex := 0;
  FBitmapData.Height := FBitmap.Height;
  FBitmapData.Width  := FBitmap.Width;
  SetLength( FBitmapData.Dots, FBitmap.Width * FBitmap.Height );

  for LY := 0 to FBitmap.Height-1 do begin
    LLine := FBitmap.ScanLine[LY];

    for LX := 0 to FBitmap.Width-1 do begin
      LPixel := LLine[LX];
      LLum   := Trunc( ( LPixel.rgbtRed * 0.3 ) + ( LPixel.rgbtGreen  * 0.59 ) + ( LPixel.rgbtBlue * 0.11 ) );

      FBitmapData.Dots[LIndex] := ( LLum < FLumThreshold );

      Inc( LIndex );
    end;

  end;
end;

function TssESCPosPrintBitmap.RenderBitmap( const ABitmapFilename: string): string;
var
  LOffset     : Integer;
  LX          : Integer;
  LSlice      : Byte;
  LB          : Integer;
  LK          : Integer;
  LY          : Integer;
  LI          : Integer;
  LV          : Boolean;
  LVI         : Integer;
begin
  // *** load the Bitmap from the file
  FBitmap.LoadFromFile( ABitmapFilename );
  FBitmap.PixelFormat := pf24bit;

  // *** Convert the bitmap to an array of B/W pixels
  LoadBitmapData();


  // *** Set the line spacing to 24 dots, the height of each "stripe" of the
  // *** image that we're drawing
  Result := #27'3'#24;

  LOffset := 0;
  while ( LOffset < FBitmapData.Height ) do begin
    Result := Result + #27;
    Result := Result + '*'; // Bit image mode
    Result := Result + #33; // 24-dot double density
    Result := Result + Char( Lo( FBitmapData.Width ) );
    Result := Result + Char( Hi( FBitmapData.Width ) );

    for LX := 0 to FBitmapData.Width -1 do begin
      for LK := 0 to 2 do begin
        LSlice := 0;
        for LB := 0 to 7 do begin
          LY := ( ( ( LOffset div 8 ) + LK ) * 8 ) + LB;
          LI := ( LY * FBitmapData.Width ) + LX;

          LV := False;
          if ( LI < Length( FBitmapData.Dots ) ) then
            LV := FBitmapData.Dots[LI];

          LVI := IfThen( LV, 1, 0 );

          LSlice := LSlice or ( LVI shl ( 7 - LB ) );
        end;

        Result := Result + Chr( LSlice );
      end;
    end;

    LOffset := LOffset + 24;
    Result := Result + sLineBreak;  
  end;

  // *** Restore the line spacing to the default of 30 dots
  Result := Result + #27'3'#30 + sLineBreak + sLineBreak + sLineBreak;
end;

Function TfrmEpsonPrint.PrintLabel(EPLCode : String): Boolean;
var
  ADevice, ADeviceName, ADevicePort: array[0..255]of Char;
  PrinterHandle: THandle;
  DocInfo: TDocInfo1;
  dwJob: cardinal;
  dwBytesWritten: cardinal;
  AUtf8: UTF8string;
  ADeviceMode: THandle;
  Index: Integer;
begin
  Try
    Try
      Result := True;
      //printer
      Printer.Refresh;
      Index := Printer.Printers.IndexOf('EPSON TM-T82 Receipt');
      If Index >= 0 Then
        Printer.PrinterIndex := Index
      Else
      Begin
        ShowMessage('EPSON TM-T82 Receipt Printer not found. Please add Generic/Text Only Printer with name 2824');
        Result := False;
        Exit;
      End;
      Printer.GetPrinter(ADevice, ADeviceName, ADevicePort, ADeviceMode);

      //Need a handle to the printer
      if not OpenPrinter(ADevice, PrinterHandle, nil) Then
        Exit;

      //Fill in the structure with info about this "document"
      DocInfo.pDocName := PChar('Label.txt');
      DocInfo.pOutputFile := nil;
      DocInfo.pDatatype := 'RAW';

      //Inform the spooler the document is beginning
      dwJob := StartDocPrinter(PrinterHandle, 1, @DocInfo);
      if dwJob = 0 then
      begin
        ClosePrinter(PrinterHandle);
        PrinterHandle := 0;
        Exit;
      end;

      //Start a page
      if not StartPagePrinter(PrinterHandle) then
      begin
        EndDocPrinter(PrinterHandle);
        ClosePrinter(PrinterHandle);
        PrinterHandle := 0;
        Exit;
      end;

      EPLCode :=  _ESCPosPrintBitmap.RenderBitmap('C:\POS\RecTopImage1.bmp');
     // EPLCode := EPLCode + #29'V'#1;

      //epl code...
      AUtf8 := UTF8string(EPLCode);
      WritePrinter(PrinterHandle, @AUtf8[1], Length(AUtf8), dwBytesWritten);

      //End the page
      if not EndPagePrinter(PrinterHandle) then
      begin
        EndDocPrinter(PrinterHandle);
        ClosePrinter(PrinterHandle);
        PrinterHandle := 0;
        Exit;
      end;

      //Inform the spooler that the document is ending
      if not EndDocPrinter(PrinterHandle) then
      begin
        ClosePrinter(PrinterHandle);
        PrinterHandle := 0;
        Exit;
      end;
      //Tidy up the printer handle
      ClosePrinter(PrinterHandle);
      PrinterHandle := 0;
    Except
    End;
  Finally
    PrinterHandle := 0;
  End;
End;

Image of print-out

1 个答案:

答案 0 :(得分:0)

每行为24点,每行为8行,每行3个点。但是当你输出3行时,你已经减少了2个点。尝试将行间距设置为22点。取代

Result := #27'3'#24;

Result := #27'3'#22;

(或者,如果这不起作用,请将其设置为21.我不确定您是否已经过2点或3点。)