BitBlt Printer.Canvas в TBitMap отображается белым цветом

Я пытаюсь захватить Printer.Canvas как растровое изображение, используя BitBlt. Я хочу взять это растровое изображение и отобразить его на коробке с красками. Однако, когда я пытаюсь это сделать, мне дают только белый прямоугольник, пропорциональный значениям, которые я ввел для Bitmap.SetSize. Моя распечатка выглядит правильно, поэтому я почти уверен, что холст принтера правильно нарисован. Я попытался использовать следующий код, используя переменную растровое изображение в качестве места назначения и ящик для рисования в качестве источника (по сути я рисовал простой прямоугольник и строку текста в Paintbox, помещая его в растровое изображение, очищая его, а затем публикуя его обратно в ящик для рисования), но теперь, когда Printer.Canvas. Handle является источником, который он не отображает.

Я понимаю, что размеры между экраном и принтером разные, поэтому я четко укажу размеры на всякий случай, если я делаю это неправильно.

procedure TForm2.btnDrawClick(Sender: TObject);
begin
  Printer.BeginDoc;
  Printer.Canvas.Font.Size := 10; //Not Sure if this is necessary
  Printer.Canvas.Font.Name := 'Arial'; //Not Sure if this is necessary
  Printer.Canvas.Font.Color := clBlack; //Not Sure if this is necessary
  Printer.Canvas.Rectangle(100,100,200,200); //Should print very tiny to paper
                                             //But will look bigger when posted to 
                                             //The Paintbox
  Printer.Canvas.TextOut(120,120,'XRay-Cat');
  PCBitmap.SetSize(Paintbox1.Width,Paintbox1.Height); //Paint box is 300W,300H
  Application.ProcessMessages;
  BitBlt(PCBitmap.Canvas.Handle, //PCBitmap, is created on create, freed on destroy,
                                 //Defined in the private section                            
         0,
         0,
         PCBitmap.Width, //300
         PCBitmap.Height, //300
         Printer.Canvas.Handle,
         0,
         0,
         SRCCOPY);
  Application.ProcessMessages;
  Printer.EndDoc;

procedure TForm2.btnPostBMClick(Sender: TObject);
begin
  PaintBox1.Canvas.Draw(0,0,PCBitmap); 
end;

Я ожидаю, что холст будет также написан, холст будет скопирован в растровое изображение, а затем будет доступен для рисования на коробке краски. Однако все, что я вижу, это белый прямоугольник. Я устанавливаю размеры растрового изображения, чтобы оно было целиком, а не целым полотном принтера. Я делаю это, потому что, если я правильно понимаю, я должен рисовать только между TopLeft 0,0 и BottomRight 300,300 холста принтера так же, как на своем блоке рисования. Я ожидал бы увидеть те же результаты, что и я, если бы сделал это непосредственно с Paintbox.

Любая помощь будет принята с благодарностью. Заранее спасибо.

Учитывая комментарии, которые я получил, кажется, что я пытался сделать это было невозможно. Я хотел написать на холсте принтеров, а затем получить данные изображения этого холста и сохранить его в растровом изображении. Поскольку BitBlt не может быть использован, есть ли способ сделать то, что я хотел? Я предполагаю, что нет, как мне сказали Printer.Canvas не может быть прочитан из. На данный момент я нашел способ обойти это, но мне просто любопытно.

1 ответ

Переключите свою логику... рисуйте в PaintBox... и распечатайте PaintBox

procedure TForm55.Button1Click(Sender: TObject);
var
  a_BM: TBitMap;
begin
  a_BM := TBitmap.Create;
  try

    PaintBox1.Canvas.Font.Size := 10; //Not Sure if this is necessary
    PaintBox1.Canvas.Font.Name := 'Arial'; //Not Sure if this is necessary
    PaintBox1.Canvas.Font.Color := clBlack; //Not Sure if this is necessary
    PaintBox1.Canvas.Rectangle(0,0,300,300); //Should print very tiny to paper
                                               //But will look bigger when posted to
                                               //The Paintbox
    PaintBox1.Canvas.TextOut(120,120,'XRay-Cat');
    PaintBox1.Width := 300;
    PaintBox1.Height := 300;
    a_BM.SetSize(PaintBox1.Width, PaintBox1.Height);
    BitBlt(a_BM.Canvas.Handle, 0, 0, a_BM.Width, a_BM.Height, PaintBox1.Canvas.Handle, 0, 0, SRCCOPY);
    Application.ProcessMessages;
    Printer.BeginDoc;
    Printer.Canvas.Draw(a_BM.Canvas.ClipRect.Left, a_BM.Canvas.ClipRect.Top, a_BM);
    Printer.EndDoc;
    Application.ProcessMessages;
  finally
    a_BM.Free;
  end;
end;
Другие вопросы по тегам