Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.28;
Скачать: CL | DM;

Вниз

Создать TBitmap "с нуля" в электронном виде.   Найти похожие ветки 

 
Курдль ©   (2004-03-05 14:30) [0]

Здоровствуйте, коллеги и сочувствующие!
Не могу найти полного описания сего процесса (см. сабж).
Мне надо создать полноценный TBitmap для вывода его как на экран, так и на принтер. Т.е. прописать ему все требуемые свойства и набить этот мэп, собснно, битами изображения "от руки" (или из заранее заготовленного массива).
Типа как на Java "createImage(new MemoryImageSource(...))"


 
SammIk ©   (2004-03-05 14:34) [1]

Берешь в поисковике забиваешь
Формат фаила BMP
И гуляешь в поисках нужного дока


 
TUser ©   (2004-03-05 14:36) [2]


> Создать TBitmap "с нуля"

MyBitMap:=TBitMap.Create;
Потом задать Width и Height, нарисовать чаго-нибудь и вперед ...


 
Курдль ©   (2004-03-05 14:56) [3]


> MyBitMap:=TBitMap.Create;
> Потом задать Width и Height, нарисовать чаго-нибудь и вперед
> ...


Нарисовать в канве - это примитивно!
Да и может не прокатить, ведь канвы-то бывают разные!
Мне надо какой-нить универсальный алгоритм инициализации.

Кстати, если просто рисовать, то принтер его не съедает.
Зато если сначала его грузануть из файла (LoadFromFile),
а уж потом накалякать поверх, то все нормально выводится...
Парадокс...


 
BOA_KAA ©   (2004-03-05 15:07) [4]

> Нарисовать в канве - это примитивно!
> Да и может не прокатить, ведь канвы-то бывают разные!

Бывает же...

>  если просто рисовать, то принтер его не съедает

Это как?


 
pasha_golub ©   (2004-03-05 15:14) [5]

Курдль ©   (05.03.04 14:56) [3]
А вы орехи любите?


 
KSergey ©   (2004-03-05 15:17) [6]

>  [4] BOA_KAA ©   (05.03.04 15:07)
> >  если просто рисовать, то принтер его не съедает
>
> Это как?

Выплевывает ;)


 
Курдль ©   (2004-03-05 15:18) [7]

> BOA_KAA
Вы помочь хотите, или сотрясаетесь от собственной значимости?

   prnBitmap.LoadFromFile("1.bmp");
   prnBitmap.Canvas.FillRect(Rect(10, 10, 20, 20));
   Printer.BeginDoc;
   Printer.Canvas.Draw(0,0,prnBitmap);
   Printer.EndDoc;

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

Вот я спрашиваю, какие свойства битмап берет из подгружаемого файла, которые позволяют ему нормально отображаться (Width и Height не предлагать).


 
KSergey ©   (2004-03-05 15:20) [8]

>  [7] Курдль ©   (05.03.04 15:18)
> (Width
> и Height не предлагать).

Это почему, интересно??
Без первой строчки лично я не вижу где вы их задаете...


 
BOA_KAA ©   (2004-03-05 15:21) [9]

> Вы помочь хотите, или сотрясаетесь от собственной значимости?

Второе.

> Без 1-й строчки на принтер выводится чистый лист.

Нет, он печатает белый квадрат, если Вам так легче ;)


 
Семен Сорокин ©   (2004-03-05 15:22) [10]

Курдль ©   (05.03.04 15:18) [7]
н-да, советую прислушаться к товарищам, почитать информацию, по Canvas"у в частности, а потом уже рассуждать.

ЗЫ. А орехи все-таки любите :))


 
sniknik ©   (2004-03-05 15:22) [11]

а если так?

prnBitmap.Canvas.Brush.Color:= clBlack;
prnBitmap.Canvas.FillRect(Rect(10, 10, 20, 20));
Printer.BeginDoc;
Printer.Canvas.Draw(0,0,prnBitmap);
Printer.EndDoc;


 
Семен Сорокин ©   (2004-03-05 15:27) [12]

sniknik ©   (05.03.04 15:22) [11]
не лучше так, так красивее, Малевич отдыхает :))

prnBitmap.Width := Printer.PageWidth;
prnBitmap.Height := Printer.PageHeight;
prnBitmap.Canvas.Brush.Color:= clBlack;
prnBitmap.Canvas.FillRect(Rect(10, 10, Printer.PageWidth-10, Printer.PageHeight-10));
Printer.BeginDoc;
Printer.Canvas.Draw(0,0,prnBitmap);
Printer.EndDoc;


 
BOA_KAA ©   (2004-03-05 15:31) [13]

> Семен Сорокин ©   (05.03.04 15:27) [12]

Не, он так квадратом не будет :)


 
pasha_golub ©   (2004-03-05 15:33) [14]

var
B: TBitmap;
begin
B := TBitmap.Create;
try
B.Width := 400;
B.Height := 400;
B.Canvas.Brush.Color := clBlack;
B.Canvas.FillRect(Rect(10,10,100,100));
Printer.BeginDoc;
Printer.Canvas.Draw(0,0,B);
Printer.EndDoc;
finally
B.Free;
end;
end;


 
Курдль ©   (2004-03-05 15:33) [15]


> не лучше так, так красивее, Малевич отдыхает :))


Ну и как, ЭТО у Вас напечаталось? У меня - нет!   :(


 
MBo ©   (2004-03-05 15:40) [16]

>Курдль
1. Tbitmap.Create
  установить width, height и при необходимости глубину цвета
  размеры могут быть произвольны (тогда вывод на принтер со Stretch-ингом) или задаваться по GetDeviceСaps принтера

2. CreateCompatibleBitmap c контекстом принтера

Заполнить из массива - одни из путей - SetDiBits


 
KSergey ©   (2004-03-05 15:44) [17]

> [15] Курдль ©   (05.03.04 15:33)
> Ну и как, ЭТО у Вас напечаталось? У меня - нет!   :(

А у меня - да! :)

Можно ваш код полностью полюбопытствовать? Который на основе [12] Семен Сорокин ©   (05.03.04 15:27) сделан?

PS
Я надеюсь - принтер у вас есть? ;)


 
Курдль ©   (2004-03-05 15:46) [18]

> MBo ©
Вот и мастера пожаловали!
1. Ни один из приведенных выше примеров (за исключением моего первоначального с загрузкой из файла) ничего не печатают.
2. CreateCompatibleBitmap c контекстом принтера подразумевает создание HBITMAP при наличии работающего принтера.
У меня же сложная графика из одного и того же битмапа (ранее созданного) должна быть видна на экране и печататься на принтере.


 
KSergey ©   (2004-03-05 15:48) [19]

Код в конце-концов можно увидеть??? Полный, относящийся к делу.


 
Курдль ©   (2004-03-05 15:52) [20]

Код в конце-концов можно увидеть??? Полный, относящийся к делу.

Вот, пжалста - в сильно усеченном виде (но тож не работает):

procedure TGantt2D.PrintStretch;
var prnBitmap: TBitmap;
//    prnDC: HDC;
//    prnBitmap: HBITMAP;
begin
 prnBitmap := TBitmap.Create;
 prnBitmap.Width := 200;
 prnBitmap.Height := 200;
 try
   prnBitmap.Width := Printer.PageWidth;
   prnBitmap.Height := Printer.PageHeight;
   prnBitmap.Canvas.Brush.Color:= clBlack;
   prnBitmap.Canvas.FillRect(Rect(10, 10, Printer.PageWidth-10, Printer.PageHeight-10));
   Printer.BeginDoc;
   try
     Printer.Canvas.Draw(300,300,prnBitmap);
     Printer.EndDoc;
   except
     Printer.Abort;
   end;
 finally
   prnBitmap.Free;
 end;
end;


 
Семен Сорокин ©   (2004-03-05 15:59) [21]

наверное принтер не цветной, добавь после создания:
prnBitmap.PixelFormat := pf1bit;
или
prnBitmap.Monohrome := true;


 
pasha_golub ©   (2004-03-05 16:03) [22]

Семен Сорокин ©   (05.03.04 15:59) [21]
Это к делу врядлле относится. :-)


 
KSergey ©   (2004-03-05 16:03) [23]

> [20] Курдль ©   (05.03.04 15:52)
> Вот, пжалста - в сильно усеченном виде (но тож не работает):

Вот буквально приведенный код у меня печатает. Черный прямоугольник почти на весь лист.


 
Курдль ©   (2004-03-05 16:04) [24]


> prnBitmap.PixelFormat := pf1bit;


ЙЙЙЙЙЙес!
Я пробовал на 3-х разных лазерниках, но про формат мне мысль не приходила!

Спасибо!


 
pasha_golub ©   (2004-03-05 16:09) [25]

Курдль ©   (05.03.04 16:04) [24]

И что проблема была в формате?
Не верю (с) Станиславский


 
WebErr ©   (2004-03-05 16:11) [26]

Доступ к отдельным точкам, а точнее строкам, компонента TBitmap осуществляется с помощью property ScanLine[i], i - это индекс нужной строки битмапа, причём учитывая, что битмап загружается "вверх ногами" - это индексация "снизу-вверх".

property ScanLine[Row: Integer]: Pointer;

Далее преобразуете Pointer к PChar, прибавляете к указателю на char нужное значение (X*BytesPerPixel). И работаете с указателем на точку. :))))


 
Семен Сорокин ©   (2004-03-05 16:11) [27]

pasha_golub ©   (05.03.04 16:09) [25]
И что проблема была в формате?

было у меня похожее на лазернике HP 1200-PCL под 2000, пока не установил нужный формат - печатал белый лист.


 
BOA_KAA ©   (2004-03-05 16:14) [28]

> И что проблема была в формате?

Вполне реально для HP с PCL. Дальше еще прикольнее может быть ;)


 
Курдль ©   (2004-03-05 16:21) [29]


> И что проблема была в формате?


> Вполне реально для HP с PCL.

LG, HP и Lexmark...


> WebErr ©

ScanLine[i] дает указатель на точки физического устройства (видеокарты, принтера и т.д.).
Считаю, что работа с ними - не корректна. Если Вы имеете другое мнение и опыт - рад послушать.


 
WebErr ©   (2004-03-05 16:34) [30]


> ScanLine[i] дает указатель на точки физического устройства
> (видеокарты, принтера и т.д.).
> Считаю, что работа с ними - не корректна. Если Вы имеете
> другое мнение и опыт - рад послушать.

:))))
Это-ж битмап!!! Сам по себе он ни с каким устройством не связан!!! Я очень часто использую свойство ScanLine[i] и пока безо всяких приключений, чего и Вам советую! :))))
Так что вопрос о корректности использования ScanLine pointer"a прошу считать некорректным! :))))
А вот когда Вы сотворяете Canvas.Draw/StretchDraw(TBitmap), вот тогда всё, что попадёт на устройство будет на вашей совести!!! :))))

procedure TForm1.FormCreate(Sender: TObject);
var
 P: Pointer;
begin
Bitmap1 := TBitmap.Create;
 Bitmap2 := TBitmap.Create;
 Bitmap2.LoadFromFile("C:\Work\Apteka-V\Bitmaps\Ãàëî÷êà.bmp");
Bitmap1.Width := 16;
 Bitmap1.Height := 16;
 Bitmap1.PixelFormat := pf24bit;
 Bitmap1.IgnorePalette := true;
 P := Bitmap1.ScanLine[15]; // this bitch is turned!!!
 FillChar(P^, 3*16*16, 64);
end;

Это как пример работающего кода! ;)


 
BOA_KAA ©   (2004-03-05 16:42) [31]

> Курдль ©

Почитай-ка здесь: http://www.gnomehome.demon.nl/uddf/pages/printer.htm


 
Курдль ©   (2004-03-05 16:43) [32]

> WebErr

Спасибо! Особенно понравилось "this bitch is turned!!!
" :)

А альтернативы нет, типа распределить память, разметить ее  в соотв. с картинкой и сделать какой-нить "Assign..."?..


 
Курдль ©   (2004-03-05 16:48) [33]


> BOA_KAA

Спасибо! Это как раз ТО_САМОЕ, начиная с:

procedure DrawImage(Canvas: TCanvas; DestRect: TRect; ABitmap:
TBitmap);
var
 Header, Bits: Pointer;
 HeaderSize: Integer;
 BitsSize: Longint;
begin
 GetDIBSizes(ABitmap.Handle, HeaderSize, BitsSize);
 Header := MemAlloc(HeaderSize);
 Bits := MemAlloc(BitsSize);
 try
   GetDIB(ABitmap.Handle, ABitmap.Palette, Header^, Bits^);
   StretchDIBits(Canvas.Handle, DestRect.Left, DestRect.Top,
       DestRect.Right, DestRect.Bottom,
       0, 0, ABitmap.Width, ABitmap.Height, Bits,TBitmapInfo(Header^),
       DIB_RGB_COLORS, SRCCOPY);
   { you might want to try DIB_PAL_COLORS instead, but this is well
     beyond the scope of my knowledge. }
 finally
   MemFree(Header, HeaderSize);
   MemFree(Bits, BitsSize);
 end;
end;


 
WebErr ©   (2004-03-05 16:49) [34]

Да! И не забудьте, что у битмапа длинна каждой строки в байтах кратна 4 - это, так называемое "выравнивание по двойному слову". То есть битмап, с шириной не кратной 4, дополняется нулевыми байтами в конце строки.
Значит для Bitmap1.Width := N длина строки битмапа вычисляется по формуле [Round](N*BytesPerPixel+3) and $7FFFFFFC. Где BytesPerPixel может быть и Real (или Double), и Integer.


 
WebErr ©   (2004-03-05 16:57) [35]


> Спасибо! Особенно понравилось "this bitch is turned!!!
> " :)

Строку удалить забыл - напоминание о том, как долго я искал ошибку при закраске моего битмапа, и о том как долго я на него ругался! :)

> А альтернативы нет, типа распределить память, разметить
> ее  в соотв. с картинкой и сделать какой-нить "Assign..."?..

Есть такая штука! :)
Создаёте буффер с байтами картинки, которую вы сами ручками создадите, а потом StretchDIBits/SetDIBitsToDevice - это кульные апишные функции, которые очень быстро работают (стретч работает на порядок медленнее!) :))))


 
Курдль ©   (2004-03-10 12:34) [36]

Семен Сорокин ©

> наверное принтер не цветной, добавь после создания:
> prnBitmap.PixelFormat := pf1bit;
> или
> prnBitmap.Monohrome := true;


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

1. prnBitmap.Monohrome := true; не помогает (это как раз и понятно)
2. Но не понятно, почему значение, полученное от принтера ф-цией GetDeviceCaps(Printer.Handle, BITSPIXEL) и подставленное битмапу (в моем частном случае - pf24bit) опять же вызывает печать белого листа.
(Для тех, кто не в курсе, речь идет о черно-белых лазерниках)



Страницы: 1 вся ветка

Текущий архив: 2004.03.28;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.062 c
14-1078351819
pirat
2004-03-04 01:10
2004.03.28
где бы достать библиотеку для работы с БОЛЬШИМИ числами по модулю


1-1078592161
Rustamus
2004-03-06 19:56
2004.03.28
Поиск


3-1077493659
HMT
2004-02-23 02:47
2004.03.28
TIBEvents..Что-то не работает :-(


1-1078400588
ChcngerMan
2004-03-04 14:43
2004.03.28
Internet+computer


14-1077629077
raymond
2004-02-24 16:24
2004.03.28
Друзья, как мне скопировать копию рабочего стола в буфер?