Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

printing a BMP

Status
Not open for further replies.

safra

Technical User
Jan 24, 2001
319
NL
Hi,

Apparantly there are several issues with printing a bitmap (such as the size).

The code below should solve most of them:

Code:
var
  Info: PBitmapInfo;
  InfoSize: DWORD;
  Image: Pointer;
  ImageSize: DWORD;
  Bits: HBITMAP;
  DIBWidth, DIBHeight: LongInt;
begin
  Printer.BeginDoc;
  try
    Canvas.Lock;
    try
      { Paint bitmap to the printer }
      with Printer do
      begin
        Bits := bmp.Handle;
        GetDIBSizes(Bits, InfoSize, ImageSize);
        Info := AllocMem(InfoSize);
        try
          Image := AllocMem(ImageSize);
          try
            GetDIB(Bits, 0, Info^, Image^);
            with Info^.bmiHeader do
            begin
              DIBWidth := biWidth;
              DIBHeight := biHeight;
            end;
            StretchDIBits(Canvas.Handle, 0, 0, DIBWidth, DIBHeight, 0, 0,
              DIBWidth, DIBHeight, Image, Info^, DIB_RGB_COLORS, SRCCOPY);
          finally
            FreeMem(Image, ImageSize);
          end;
        finally
          FreeMem(Info, InfoSize);
        end;
      end;
    finally
      Canvas.Unlock;
    end;
  finally
    Printer.EndDoc;
  end;
end;
However, the bitmap is still printed rather small, anyone knows how to deal with this?

Thanks,
Raoul

 
The printer canvas have the same density (dots per inch) as a monitor canvas, but a real printer have very different DPI values, so you need to rescale the size before calling "stretch".

a) Get your printer DPI calling GetDeviceCaps with the printer handler and the constants LOGPIXELSX and LOGPIXELSY.

Code:
function XpelsPerInch : integer;
  begin
    XpelsPerInch := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
  end;

function YpelsPerInch : integer;
  begin
    YpelsPerInch := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
  end;

b) Create two "scale" functions, able to translate between the canvas DPIs and the real device DPIs.

Code:
const
  DPIS = 96;  // Monitor DPI - same for x and y axis.
function  XrenderFactor : single;
  begin
    XrenderFactor := XpelsPerInch / DPIS;
  end;
function  YrenderFactor : single;
  begin
    YrenderFactor := YpelsPerInch / DPIS;
  end;

c) Calculate the needed bitmap sizes to print the bitmap WYSIWYG (actually WYSIQWYG):

Code:
x2 := Round(DIBWidth * XrenderFactor)
y2 := Round(DIBHeight * YrenderFactor)

x2 and y2 are the sizes you need to pass to "stretch" as the destination rectangle sizes (first two DIBWidth and DIBHeight in your code).

Of course, you can do things like

Code:
x2 := Round(DIBWidth * XrenderFactor / n)
y2 := Round(DIBHeight * YrenderFactor / n)

to reduce the bitmap n times related to how you see it in the screen.

HTH.

buho (A).
 
Hi,

Thanks Buho,

I was under the impression that the code I posted deals with the printer density issue.

I will try what you suggested.

Thanks,
Raoul




(For some reason I can't login with the 'safra' username since Saturday.)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top