加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使用Delphi 6使用StretchDIBits处理条形码图像 – 输出中缺少条

发布时间:2020-12-15 09:13:48 所属栏目:大数据 来源:网络整理
导读:我的应用程序是在Delphi 6中开发的.由于后台处理和大量数据,它是一个资源集成应用程序(它消耗大约60MB – 120MB的物理内存).该应用程序的一个功能是在进行某些处理后创建条形码图像. 如果用户继续生成条形码,那么至少十分之一的条形码中缺少一行. 我们在生成
我的应用程序是在Delphi 6中开发的.由于后台处理和大量数据,它是一个资源集成应用程序(它消耗大约60MB – 120MB的物理内存).该应用程序的一个功能是在进行某些处理后创建条形码图像.
如果用户继续生成条形码,那么至少十分之一的条形码中缺少一行.
我们在生成输出时有以下步骤:

>在内存中创建条形码图像(TImage).图像的高度为10像素.我们使用pf24bit像素格式.
>根据打印机的画布??调整内存中的图像大小并将其传递到打印机的画布??.
步骤#2的代码如下:

procedure PrintBitmap(ARect:TRect; Bitmap:TBitmap);
var
  Info: PBitmapInfo;
  InfoSize: dword{Integer};
  Image: Pointer;
  ImageSize: dword{ integer};
  iReturn : integer ;
  iWidth,iHeight :integer;
begin
try
  with Bitmap do
  begin
     iReturn := 1;
     GetDIBSizes( Handle,InfoSize,ImageSize );
     GetMem( Info,InfoSize );
     try
        getMem( Image,ImageSize );
        try
           GetDIB(Handle,Palette,Info^,Image^);
           try
             with Info^.bmiHeader do
             begin
                SetStretchBltMode(Printer.Canvas.handle,HALFTONE);
                iReturn := **StretchDIBits**(Printer.Canvas.Handle,ARect.Left,ARect.Top,ARect.Right - ARect.Left,ARect.Bottom - ARect.Top,biWidth,biHeight,Image,DIB_RGB_COLORS,SRCCOPY);
             end;
           except on E:Exception do
           begin
              gobjLog.pWritetoLog(0,'RptWrks2','PrintBitmap','Exception in StretchDIBits with message '+e.Message);
           end;
           end
        finally
           FreeMem(Image,ImageSize);
        end;
     finally
        FreeMem(Info,InfoSize);
     end;
end
except on E:Exception do
begin
    gobjLog.pWritetoLog(0,'Exception in PrintBitMap with message '+e.Message);
end;

end;

我们检查了问题在于步骤#2,因为生成的条形码图像没有任何问题. (我们注释掉了步骤#2并将输出作为BMP文件来确认).

此外,我们尝试了以下解决方法:

>我们使用TExcellentImagePrinter组件来执行调整大小操作.但是,问题没有得到解决.
>我们包含了SETPROCESSWORKINGSETSIZE WinAPI调用以减少/刷新应用程序使用的当前memry.
>我们在代码中包含Sleep(3000),以便Windows能够为映像分配内存.然而,包括睡眠会降低此错误发生的频率.

你能提出任何建议吗?

解决方法

我使用此功能打印条形码取得了巨大成功.它假设位图是100%缩放条形码(每个x像素是条形码条纹),高度无关紧要,它可能只有1px.

线索是用fillrect打印条形码而不是位图:
该函数只是“读取”条形码并将其填充到一些画布上.如果得到的比例(xFactor = aToRect宽度到条形码宽度)是整数或足够大的实数(对于打印机没问题),可以毫无问题地读取打印的条形码.它也适用于PDF打印机.

您只需要为位图生成100%缩放的条形码(正如您已经做的那样;高度可能是1px;条形码的颜色必须是clBlack)并将其传递给aFromBMP参数.然后aToCanvas将成为您的打印机画布. aToRect是打印机画布中的目标rect. aColor是目标条形码的颜色(可能是一切).

procedure PrintBarCodeFromBitmap(const aFromBMP: TBitmap;
  const aToCanvas: TCanvas; const aToRect: TRect;
  const aColor: TColor = clBlack);
var I,xStartRect: Integer;
  xFactor: Double;
  xColor: TColor;
  xLastBrush: TBrush;
begin
  xLastBrush := TBrush.Create;
  try
    xLastBrush.Assign(aToCanvas.Brush);

    aToCanvas.Brush.Color := aColor;
    aToCanvas.Brush.Style := bsSolid;

    xFactor := (aToRect.Right-aToRect.Left)/aFromBMP.Width;

    xStartRect := -1;
    for I := 0 to aFromBMP.Width do begin
      if I < aFromBMP.Width then
        xColor := aFromBMP.Canvas.Pixels[I,0]
      else
        xColor := clWhite;

      if (xStartRect < 0) and (xColor = clBlack) then begin
        xStartRect := I;
      end else if (xStartRect >= 0) and (xColor <> clBlack) then begin
        aToCanvas.FillRect(
          Rect(
            Round(aToRect.Left+xStartRect*xFactor),aToRect.Top,Round(aToRect.Left+I*xFactor),aToRect.Bottom));
        xStartRect := -1;
      end;
    end;
  finally
    aToCanvas.Brush.Assign(xLastBrush);

    xLastBrush.Free;
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读