title: Image on receipt from epson thermal printer shows white horizontal lines
body: <p>I have printed bitmap image from epson TM-T82 printer using delphi7 code.
  I am sending ESCPOS commands to epson printer to print bitmap image.
  This printed bitmap image contains white lines in logo.</p>
  
  <p>When I use the Epson printer utility with the same logo, it prints fine.</p>
  
  <p>Does any one know how to fix this problem?</p>
  
  <p>Here is my code :</p>
  
  <pre><code>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 &lt; 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 &lt; 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 &lt; 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 &gt;= 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;
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/H8zsx.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H8zsx.jpg" alt="Image of print-out"></a></p>