Створити TBitmap – з нуля – в електронному вигляді
Здоровайте, колеги і співчуття! Не можу знайти повного опису цього процесу (див. сабж). Мені треба створити повноцінний TBitmap для виведення його як на екран, так і на принтер. Тобто. прописати йому всі необхідні властивості і набити цей меп, власне, бітами зображення "від руки" (або із заздалегідь заготовленого масиву). Типу як на Java
Береш у пошуковику забиваєш Формат фаїлу BMP І гуляєш у пошуках потрібного дока
> Створити TBitmap "з нуля"MyBitMap:=TBitMap.Create; Потім задати Width і Height, намалювати чогось і вперед.
> MyBitMap:=TBitMap.Create; > Потім задати Width та Height, намалювати чогось і вперед > .
Намалювати в канві – це примітивно! Та й може не прокотити, адже канви-то бувають різні! Мені треба який-небудь універсальний алгоритм ініціалізації.
До речі, якщо просто малювати, то принтер його не з'їдає. Зате якщо спочатку його вантажити з файлу (LoadFromFile), а вже потім накалякати поверх, то все нормально виводиться. Парадокс.
> Намалювати в канві – це примітивно! > Та й може не прокотити, адже канви бувають різні!
> якщо просто малювати, то принтер його не з'їдає
> BOA_KAA Ви допомогти хочете, або здригаєтеся від власної значущості?
prnBitmap.LoadFromFile("1.bmp"); prnBitmap.Canvas.FillRect(Rect(10, 10, 20, 20)); Printer.BeginDoc; Printer.Canvas.Draw(0,0,prnBitmap); Printer.EndDoc;
Без першого рядка на принтер виводиться чистий лист. Якщо його ввімкнути, то принтер друкує картинку з накладеним квадратом.
Ось я питаю, які властивості бітмап бере з файлу, що підвантажується, які дозволяють йому нормально(Width і Height не пропонувати).
> Ви допомогти хочете, чи труситесь від власної значущості?
> Без першого рядка на принтер виводиться чистий лист.
Ні, він друкує білий квадрат, якщо Вам так легко;)
ЗИ. А горіхи таки любите :))
prnBitmap.Canvas.Brush.Color:= clBlack; prnBitmap.Canvas.FillRect(Rect(10, 10, 20, 20)); Printer.BeginDoc; Printer.Canvas.Draw(0, 0,prnBitmap); Printer.EndDoc;
prnBitmap.W >prnBitmap.Height := Printer.PageHeight; prnBitmap.Canvas.Brush.Color:= clBlack; prnBitmap.Canvas.FillRect(Rect(10, 10, Printer.PageWidth- .PageHeight-10)); Printer.BeginDoc; Printer.Canvas.Draw(0,0,prnBitmap); Printer.EndDoc;
Ні, він так квадратом не буде:)
var B: TBitmap; begin B := TBitmap.Create; try B.W > 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;
> не краще так, так красивіше, Малевич відпочиває:))
Ну і як це у Вас надрукувалося? У мене немає! :(
>Курдль 1. Tbitmap.Create встановити width, height і за необхідності глибину кольору розміри можуть бути довільні (тоді виведення на принтер зі Stretch-інгом) або задаватися GetDeviceСaps принтера
2. CreateCompatibleBitmap з контекстом принтера
Заповнити з масиву - одні із шляхів - SetDiBits
PS Я сподіваюся – принтер у вас є? ;)
Код зрештою можна побачити. Повний, що стосується справи.
Код зрештою можна побачити. Повний, що стосується справи.
Ось, пжалста - в сильно усіченому вигляді (але не працює):
procedure TGantt2D.PrintStretch; var prnBitmap: TBitmap; // prnDC: HDC; // prnBitmap: HBITMAP; begin prnBitmap := TBitmap.Create; prnBitmap.W > prnBitmap.Height: = 200; try prnBitmap.W > 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;
напевно принтер не кольоровий, додай після створення: prnBitmap.PixelFormat := pf1bit; або prnBitmap. Monohrome : = true;
ЙЙЙЙЙЙес! Я пробував на 3-х різних лазерниках, але про формат мені думка не приходила!
І що проблема була у форматі? Не вірю (с) Станіславський
Доступ до окремих точок, а точніше рядків, компонента TBitmap здійснюється за допомогою property ScanLine[i], i - це індекс потрібного рядка бітмапа, причому з огляду на те, що бітмап завантажується "вгору ногами" - це індексація "знизу-вгору". властивості ScanLine[Row: Integer]: Pointer; Далі перетворите Pointer до PChar, додаєте до покажчика на char потрібне значення (X*BytesPerPixel). І працюєте із покажчиком на точку.:))))
> І що проблема була у форматі?
Цілком реально для HP з PCL. Далі ще прикольніше може бути ;)
> І що проблема була у форматі?> Цілком реально для HP з PCL.LG, HP та Lexmark.
Шануй тут: http://www.gnomehome.demon.nl/uddf/pages/printer.htm
Дякую! Особливо сподобалося "this bitch is turned. " :)
А альтернативи немає, типу розподілити пам'ять, розмітити її в соотв. з картинкою і зробитиякий-нитка "Assign. ".
> 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); < Ви можете піти на спробу DIB_PAL_COLORS instead, але це добре за межею мого знання. > finally MemFree(Header, HeaderSize); MemFree(Bits, BitsSize); end; end;
Так! І не забудьте, що у бітмапа довжина кожного рядка в байтах кратна 4 - це так зване "вирівнювання за подвійним словом". Тобто бітмап, з шириною не кратною 4, доповнюється нульовими байтами в кінці рядка. Значить для Bitmap1.
> Дякую! Особливо сподобалося "this bitch is turned. ":)Рядок видалити забув - нагадування про те, як довго я шукав помилку при забарвленні мого бітмапа, і про те як довго я на нього лаявся! :)> А альтернативи немає, типу розподілити пам'ять, розмітити > її у соотв. з картинкою і зробити який-нитку "Assign. ".Є така штука! :) Створюєте буфер з байтами картинки, яку ви самі ручками створите, а потім StretchDIBits/SetDIBitsToDevice - це кульні апішні функції, які дуже швидко працюють (стретч працює на порядок повільніше!):))) )
> напевно принтер не кольоровий, додай після створення: & gt;prnBitmap.PixelFormat := pf1bit; > або > prnBitmap.Monohrome := true;
В окремому випадку все запрацювало, але залишило неприємний осад непорозуміння. Хотілося б "дотиснути це питання".