通过Printer.Canvas打印图像有以下3步
1. 将图片转换为位图
2. 将图片转换为与设备无关的图像 - GetDIB()
   - 将图像转换为与设备无关之前,需要用GetDIBSizes()获取转换时图像头信息与与图像大小所需分配的内存大小。
3. 按指定尺寸大小打印图像 - StretchDIBits示例:(Delphi 5)
PrintBitmap(bmp:TBitmap)
var
  Info      : PBitmapInfo;
  InfoSize  : DWORD;
  Image     : Pointer;
  ImageSize : DWORD;
  Bits      : HBITMAP;
begin
     Bits := bmp.Handle;  // bmp is passed as a parameter
     GetDIBSizes(Bits, InfoSize, ImageSize);
     Info := AllocMem(InfoSize);
     try
       Image := AllocMem(ImageSize);
       try
         GetDIB(Bits, 0, Info^, Image^);
          
         StretchDIBits(Printer.Canvas.Handle,
             5, 30, Bmp.Width, bmp.Height,
             0,  0, bmp.Width, bmp.Height,
             Image, Info^, DIB_RGB_COLORS, SRCCOPY);
          
       finally
         FreeMem(Image, ImageSize);
       end;
     finally
       FreeMem(Info, InfoSize);
     end;
end;这段程序在 32位的Window XP 下能正常运行,用 XPS Document Writer 图片能打印出来。
但是在64位的 Windows 7 下, 有时图片能打印出来,第二次,第三次找印,图片无法打印出来,图像区域为一片黑色的区域。

解决方案 »

  1.   

    网上有说,问题引起的原因主要是: Windows 内存与delphi内存管理机制的不兼容性。偿试过换一种内存分配函数则不会有问题。

    Info := AllocMem(InfoSize);
    Image := AllocMem(ImageSize);
    FreeMem(Image, ImageSize);
    FreeMem(Info, InfoSize);
    改为
    BitmapHeader := HeapAlloc(GetProcessHeap, 0, HeaderSize);
    BitmapImage  := HeapAlloc(GetProcessHeap, 0, ImageSize);
    HeapFree(GetProcessHeap, 0, BitmapHeader);
    HeapFree(GetProcessHeap, 0, BitmapImage);这样就不会出错了。