我做了一个画图程序(从指定文件中读如一些数据作图),大概在1024*768的分辨率下画图,打印的时候,打出来的效果不是很好(比如直线不直,就像是在windows画图里用放大镜看直线一样,特别是有一定斜度的直线.),我知道打印机的分辨率是很高的,应该能打印出的更好效果.我是这样做的.
bmp:TBitmap,                //我先定义一个bmp变量,然后在bmp的canvas中画图.
.......bmp:TBitmap.Create;paint(bmp.canvas);                             //这里调用我自己的画图过程.
......
image1.canvas.copyrect(rect1,bmp.canvas,rect2);//这里通过image1来显示.printer.begindoc;                              //开始打印.
printer.canvas.StretchDraw(rect,bmp);
printer.enddoc;还有一个问题,就是,如果我不定义一个bmp变量,而直接用TCanvas定义一个canvas变量,然后在调用我的paint过程是直接把canvas当成参数带进去,然后打印的时候用coperect(),但是这样做却不行,不知道为什么?是不是单独的一个canvas是不可写?

解决方案 »

  1.   

    单独的一个canvas是谁的canvas?你画到了哪个canvas上了。你说的打出来的效果不是很好是不是图象很大呀。
      

  2.   


    請問ghbh(我想编但是编不出来) :
    canvas一定要是誰的嗎?如果我這樣candvas :TCanvas,單獨定義一個不行嗎?我說的打出來的圖形分辨率不夠高,何在顯示器康看到的一樣,就是説沒有發揮了打印機高分辨率的優勢.
      

  3.   

    Canvas單獨定義一個通过什么来显示?你的rect是不是很大呀。打印form的例子(包括Form上的所有东西,可能不是你所需要的,但可以参考),实现的很不错:uses Printers;type
      PPalEntriesArray = ^TPalEntriesArray; {for palette re-construction}
      TPalEntriesArray = array[0..0] of TPaletteEntry;procedure BltTBitmapAsDib(DestDc : hdc;   {Handle of where to blt}
                              x : word;       {Bit at x}
                              y : word;       {Blt at y}
                              Width : word;   {Width to stretch}
                              Height : word;  {Height to stretch}
                              bm : TBitmap);  {the TBitmap to Blt}
    var
      OriginalWidth :LongInt;               {width of BM}
      dc : hdc;                             {screen dc}
      IsPaletteDevice : bool;               {if the device uses palettes}
      IsDestPaletteDevice : bool;           {if the device uses palettes}
      BitmapInfoSize : integer;             {sizeof the bitmapinfoheader}
      lpBitmapInfo : PBitmapInfo;           {the bitmap info header}
      hBm : hBitmap;                        {handle to the bitmap}
      hPal : hPalette;                      {handle to the palette}
      OldPal : hPalette;                    {temp palette}
      hBits : THandle;                      {handle to the DIB bits}
      pBits : pointer;                      {pointer to the DIB bits}
      lPPalEntriesArray : PPalEntriesArray; {palette entry array}
      NumPalEntries : integer;              {number of palette entries}
      i : integer;                          {looping variable}
    begin
    {If range checking is on - lets turn it off for now}
    {we will remember if range checking was on by defining}
    {a define called CKRANGE if range checking is on.}
    {We do this to access array members past the arrays}
    {defined index range without causing a range check}
    {error at runtime. To satisfy the compiler, we must}
    {also access the indexes with a variable. ie: if we}
    {have an array defined as a: array[0..0] of byte,}
    {and an integer i, we can now access a[3] by setting}
    {i := 3; and then accessing a[i] without error}
    {$IFOPT R+}
      {$DEFINE CKRANGE}
      {$R-}
    {$ENDIF} {Save the original width of the bitmap}
      OriginalWidth := bm.Width; {Get the screen's dc to use since memory dc's are not reliable}
      dc := GetDc(0);
     {Are we a palette device?}
      IsPaletteDevice :=
        GetDeviceCaps(dc, RASTERCAPS) and RC_PALETTE = RC_PALETTE;
     {Give back the screen dc}
      dc := ReleaseDc(0, dc); {Allocate the BitmapInfo structure}
      if IsPaletteDevice then
        BitmapInfoSize := sizeof(TBitmapInfo) + (sizeof(TRGBQUAD) * 255)
      else
        BitmapInfoSize := sizeof(TBitmapInfo);
      GetMem(lpBitmapInfo, BitmapInfoSize); {Zero out the BitmapInfo structure}
      FillChar(lpBitmapInfo^, BitmapInfoSize, #0); {Fill in the BitmapInfo structure}
      lpBitmapInfo^.bmiHeader.biSize := sizeof(TBitmapInfoHeader);
      lpBitmapInfo^.bmiHeader.biWidth := OriginalWidth;
      lpBitmapInfo^.bmiHeader.biHeight := bm.Height;
      lpBitmapInfo^.bmiHeader.biPlanes := 1;
      if IsPaletteDevice then
        lpBitmapInfo^.bmiHeader.biBitCount := 8
      else
        lpBitmapInfo^.bmiHeader.biBitCount := 24;
      lpBitmapInfo^.bmiHeader.biCompression := BI_RGB;
      lpBitmapInfo^.bmiHeader.biSizeImage :=
        ((lpBitmapInfo^.bmiHeader.biWidth *
          longint(lpBitmapInfo^.bmiHeader.biBitCount)) div 8) *
          lpBitmapInfo^.bmiHeader.biHeight;
      lpBitmapInfo^.bmiHeader.biXPelsPerMeter := 0;
      lpBitmapInfo^.bmiHeader.biYPelsPerMeter := 0;
      if IsPaletteDevice then begin
        lpBitmapInfo^.bmiHeader.biClrUsed := 256;
        lpBitmapInfo^.bmiHeader.biClrImportant := 256;
      end else begin
        lpBitmapInfo^.bmiHeader.biClrUsed := 0;
        lpBitmapInfo^.bmiHeader.biClrImportant := 0;
      end; {Take ownership of the bitmap handle and palette}
      hBm := bm.ReleaseHandle;
      hPal := bm.ReleasePalette; {Get the screen's dc to use since memory dc's are not reliable}
      dc := GetDc(0);  if IsPaletteDevice then begin
       {If we are using a palette, it must be}
       {selected into the dc during the conversion}
        OldPal := SelectPalette(dc, hPal, TRUE);
       {Realize the palette}
        RealizePalette(dc);
      end;
     {Tell GetDiBits to fill in the rest of the bitmap info structure}
      GetDiBits(dc,
                hBm,
                0,
                lpBitmapInfo^.bmiHeader.biHeight,
                nil,
                TBitmapInfo(lpBitmapInfo^),
                DIB_RGB_COLORS); {Allocate memory for the Bits}
      hBits := GlobalAlloc(GMEM_MOVEABLE,
                           lpBitmapInfo^.bmiHeader.biSizeImage);
      pBits := GlobalLock(hBits);
     {Get the bits}
      GetDiBits(dc,
                hBm,
                0,
                lpBitmapInfo^.bmiHeader.biHeight,
                pBits,
                TBitmapInfo(lpBitmapInfo^),
                DIB_RGB_COLORS);
      if IsPaletteDevice then begin
       {Lets fix up the color table for buggy video drivers}
        GetMem(lPPalEntriesArray, sizeof(TPaletteEntry) * 256);
       {$IFDEF VER100}
          NumPalEntries := GetPaletteEntries(hPal,
                                             0,
                                             256,
                                             lPPalEntriesArray^);
       {$ELSE}
          NumPalEntries := GetSystemPaletteEntries(dc,
                                                   0,
                                                   256,
                                                   lPPalEntriesArray^);
       {$ENDIF}
        for i := 0 to (NumPalEntries - 1) do begin
          lpBitmapInfo^.bmiColors[i].rgbRed :=
            lPPalEntriesArray^[i].peRed;
          lpBitmapInfo^.bmiColors[i].rgbGreen :=
            lPPalEntriesArray^[i].peGreen;
          lpBitmapInfo^.bmiColors[i].rgbBlue :=
            lPPalEntriesArray^[i].peBlue;
        end;
        FreeMem(lPPalEntriesArray, sizeof(TPaletteEntry) * 256);
      end;  if IsPaletteDevice then begin
       {Select the old palette back in}
        SelectPalette(dc, OldPal, TRUE);
       {Realize the old palette}
        RealizePalette(dc);
      end; {Give back the screen dc}
      dc := ReleaseDc(0, dc); {Is the Dest dc a palette device?}
      IsDestPaletteDevice :=
        GetDeviceCaps(DestDc, RASTERCAPS) and RC_PALETTE = RC_PALETTE;
      if IsPaletteDevice then begin
       {If we are using a palette, it must be}
       {selected into the dc during the conversion}
        OldPal := SelectPalette(DestDc, hPal, TRUE);
       {Realize the palette}
        RealizePalette(DestDc);
      end; {Do the blt}
      StretchDiBits(DestDc,
                    x,
                    y,
                    Width,
                    Height,
                    0,
                    0,
                    OriginalWidth,
                    lpBitmapInfo^.bmiHeader.biHeight,
                    pBits,
                    lpBitmapInfo^,
                    DIB_RGB_COLORS,
                    SrcCopy);  if IsDestPaletteDevice then begin
       {Select the old palette back in}
        SelectPalette(DestDc, OldPal, TRUE);
       {Realize the old palette}
        RealizePalette(DestDc);
      end; {De-Allocate the Dib Bits}
      GlobalUnLock(hBits);
      GlobalFree(hBits); {De-Allocate the BitmapInfo}
      FreeMem(lpBitmapInfo, BitmapInfoSize); {Set the ownership of the bimap handles back to the bitmap}
      bm.Handle := hBm;
      bm.Palette := hPal;  {Turn range checking back on if it was on when we started}
    {$IFDEF CKRANGE}
      {$UNDEF CKRANGE}
      {$R+}
    {$ENDIF}
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if PrintDialog1.Execute then begin
        Printer.BeginDoc;
        BltTBitmapAsDib(Printer.Canvas.Handle,
                        0,
                        0,
                        Image1.Picture.Bitmap.Width,
                        Image1.Picture.Bitmap.Height,
                        Image1.Picture.Bitmap);
        Printer.EndDoc;
      end;
    end;
    上面这个基本保持了原来的风格和比例,由于使用了DIB图像很清晰
      

  4.   

    我可以先在自己定義的Tcanvas變量中作圖之後,再用copyrect拷到image.canvas中去呀.
      

  5.   

    ghbh(我想编但是编不出来) 
    但是我这样做的结果是不行,执行程序的时候有错.
      

  6.   

    不是关键所在,对Printer.Canvas进行操作没有错,这些TPrinter已经进行了封装!想提高打印质量(包括图像显示时的图像效果)关键在于进行图像插值!如PhotoShop一样做!
      

  7.   

    ehom(?!) 说的对,如果打印的图象很大,关键在于进行图像插值!