Последние записи
- Функция рисования для печати на принтере ScanLine
- Функция CharInSet (множества) не работает для русских букв
- Вывод изображений на печать
- Посимвольный перебор строки (сравнение скорости двух методов)
- png в ico с прозрачностью и разными разрешениями
- Автоматическое создание Proxy-файлов видео с камеры DJI Osmo Action 5 Pro для Vegas
- Поиск значения и вставка текса
- Движение image по форме
- Звук в Delphi
- Экранная лупа (линза)
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - ttps://clck.ru/fCrQw
5th
Июн
Функция рисования для печати на принтере ScanLine
Posted by obzor under Delphi
Есть ли возможность что-то рисовать на принтере через ScanLine, а не через Canvas?
Напрямую использовать ScanLine на холсте принтера (TPrinter.Canvas) нельзя.
Свойство ScanLine есть только у объекта TBitmap. Оно предоставляет прямой доступ к пикселям изображения, находящегося в оперативной памяти. Принтер же работает иначе: его Canvas — это обертка над контекстом устройства Windows (Device Context), который принимает векторные команды рисования (линии, текст, полигоны) и отправляет их в диспетчер печати (Print Spooler) в виде метафайла или инструкций для драйвера. Там просто нет «сырого» массива пикселей, который можно было бы перезаписать байт за байтом.
Решение: Использование промежуточного буфера
Единственный и самый эффективный способ использовать ScanLine для печати — это создать TBitmap в памяти, сформировать на нем изображение с помощью ScanLine, а затем отправить этот битмап на принтер через стандартный метод Canvas.Draw или Canvas.StretchDraw.
Вот готовый шаблон, как это реализуется:
uses
Vcl.Printers, Vcl.Graphics, Winapi.Windows;
procedure PrintImageViaScanLine;
var
Bmp: TBitmap;
X, Y: Integer;
Row: PRGBTriple; // Для формата pf24bit (3 байта на пиксель)
begin
Bmp := TBitmap.Create;
try
// 1. Обязательно задаем формат пикселей перед использованием ScanLine
Bmp.PixelFormat := pf24bit;
// 2. Устанавливаем размеры (важный нюанс описан ниже)
Bmp.Width := 1200;
Bmp.Height := 1600;
// 3. Заполняем изображение через ScanLine
for Y := 0 to Bmp.Height - 1 do
begin
Row := Bmp.ScanLine[Y];
for X := 0 to Bmp.Width - 1 do
begin
// Пример: рисуем градиент
Row^.rgbtBlue := X mod 256;
Row^.rgbtGreen := Y mod 256;
Row^.rgbtRed := (X + Y) mod 256;
// Переходим к следующему пикселю в строке
Inc(Row);
end;
end;
// 4. Отправляем готовый битмап на принтер
Printer.BeginDoc;
try
// StretchDraw растянет ваш битмап на всю область печати.
// Если нужно сохранить пропорции, рассчитывайте прямоугольник (TRect) вручную.
Printer.Canvas.StretchDraw(Printer.Canvas.ClipRect, Bmp);
finally
Printer.EndDoc;
end;
finally
Bmp.Free;
end;
end;
Важные нюансы при работе с принтером через Bitmap
1. Разрешение (DPI) и память:
У принтеров очень высокое разрешение (обычно 300, 600 или 1200 DPI). Если вы попытаетесь создать TBitmap с размерами, точно соответствующими Printer.PageWidth и Printer.PageHeight (например, $4800 \times 6400$ пикселей для 600 DPI), этот битмап займет в памяти около 90 МБ. Это может сильно замедлить программу или вызвать ошибку Out of Memory на старых системах.
o Решение: Создавайте битмап разумного размера (например, $2000 \times 3000$), а драйвер принтера сам качественно растянет его при помощи StretchDraw.
2. Выравнивание строк (Padding):
При работе со ScanLine всегда учитывайте, что длина строки в байтах в TBitmap округляется до кратного 4 байтам (Dword alignment). Код с Inc(Row) для pf24bit работает отлично внутри одной строки, но никогда не переносите указатель Row с конца одной строки на начало следующей вручную математическим сложением — всегда запрашивайте Bmp.ScanLine[Y] для каждой новой строки.
3. Формат цвета:
Использование pf24bit (PRGBTriple) обычно является золотой серединой для графики. Если вам нужна альфа-прозрачность (хотя принтеры её обычно не поддерживают напрямую), используйте pf32bit и тип PRGBQuad.
рисовать на принтере через ScanLine, а не через Canvas?
Похожие статьи
Купить рекламу на сайте за 1000 руб
пишите сюда - alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту

пеллетные котлы

Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
- Delphi форумы
- Форумы C (Си)
- Форум .NET Frameworks (точка нет фреймворки)
- Форум Java (джава)
- Форум низкоуровневое программирование
- Форум VBA (вба)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)


