Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Пример быстрой работы с графикой

Delphi , Графика и Игры , Графика

Пример быстрой работы с графикой

Автор: Koster

Пример быстрой работы с графикой в среде Windows без использования средств DirectX Совместимость: Windows 95, 98, NT, 2000, Me, TrE, XP, Whistler, Tristler :))


// © Koster < mtaurus@rambler.ru >
// Greetz to: Vano aka RIS, Uras aka Assargadon
// Special thanx to: Leon the Trillennium
 
unit VisualForm;

interface


uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Buttons, ComCtrls;

type
  TfmMain = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    pbDraw: TPaintBox;
    Timer1: TTimer;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
    procedure CreateBitmap(aSX, aSY: Integer);
    procedure RecreateBitmap(aSX, aSY: Integer);
    procedure DeleteBitmap;

    procedure RestrictSize(var msg: TMessage); message WM_GETMINMAXINFO;
    procedure pbDrawPaint(Sender: TObject);
  private
    ScrBitmap: TBitmap;
    Scr: Pointer;
    SX, SY: Integer;
  public
    { Public declarations }
  end;

var
  fmMain: TfmMain;

implementation

{$R *.DFM}

type
  TBig = array[0..0] of Integer;

procedure TfmMain.CreateBitmap(aSX, aSY: Integer);
var
  BInfo: tagBITMAPINFO;
begin
  // Создание DIB
  SX := aSX; SY := aSY;
  BInfo.bmiHeader.biSize := sizeof(tagBITMAPINFOHEADER);
  BInfo.bmiHeader.biWidth := SX;
  BInfo.bmiHeader.biHeight := -SY;
  BInfo.bmiHeader.biPlanes := 1;
  BInfo.bmiHeader.biBitCount := 32;
  BInfo.bmiHeader.biCompression := BI_RGB;
  ScrBitmap := TBitmap.Create();
  ScrBitmap.Handle := CreateDIBSection(Canvas.Handle, BInfo, DIB_RGB_COLORS, Scr, 0, 0);
  ZeroMemory(Scr, SX * SY * 4);
end;

procedure TfmMain.DeleteBitmap;
begin
  // Удаление DIB
  ScrBitmap.FreeImage();
  ScrBitmap.Destroy;
end;

procedure TfmMain.RecreateBitmap(aSX, aSY: Integer);
var
  BInfo: tagBITMAPINFO;
begin
  // Пересоздание DIB при изменении размеров "экрана"
  ScrBitmap.FreeImage();
  SX := aSX; SY := aSY;
  BInfo.bmiHeader.biSize := sizeof(tagBITMAPINFOHEADER);
  BInfo.bmiHeader.biWidth := SX;
  BInfo.bmiHeader.biHeight := -SY;
  BInfo.bmiHeader.biPlanes := 1;
  BInfo.bmiHeader.biBitCount := 32;
  BInfo.bmiHeader.biCompression := BI_RGB;
  ScrBitmap.Handle := CreateDIBSection(Canvas.Handle, BInfo, DIB_RGB_COLORS, Scr, 0, 0);
  ZeroMemory(Scr, SX * SY * 4);
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  CreateBitmap(pbDraw.ClientWidth, pbDraw.ClientHeight);
  pbDraw.Canvas.Draw(0, 0, ScrBitmap);
  Caption := 'Визуализатор'; Application.Title := Caption;
end;

procedure TfmMain.FormDestroy(Sender: TObject);
begin
  DeleteBitmap();
end;

procedure TfmMain.FormResize(Sender: TObject);
begin
  ReCreateBitmap(pbDraw.ClientWidth, pbDraw.ClientHeight);
  pbDraw.Canvas.Draw(0, 0, ScrBitmap);
end;

procedure TfmMain.RestrictSize(var msg: TMessage);
var
  p: PMinMaxInfo;
begin
  // Ограничитель размеров окна (обработка сообщений Windows).
  // Удобная вещь кстати (важно: см. объявление процедуры в классе TFmMain)
  // The lParam contains a pointer on a structure of type TMinMaxInfo
  p := PMinMaxInfo(Msg.lParam);
  // This represents the size of the Window when Maximized
//  p.ptMaxSize.x := 320;
//  p.ptMaxSize.y := 240;
  // This represents the position of the Window when Maximized
//  p.ptMaxPosition.x := 10;
//  p.ptMaxPosition.y := 10;
  // This represents the minimum size of the Window
  p.ptMinTrackSize.x := 520;
  p.ptMinTrackSize.y := 240;
  // This represents the maximum size of the Window
//  p.ptMaxTrackSize.x := 400;
//  p.ptMaxTrackSize.y := 320;
end;

procedure TfmMain.pbDrawPaint(Sender: TObject);
begin
  pbDraw.Canvas.Draw(0, 0, ScrBitmap);
end;

Пример работы с данной конструкцией:
SX - текущий размер нашего "экрана" по горизонтали
SY - по вертикали
TBig(Scr^). Scr - это указатель на массив пикселей битмапа, который в нашем случае имеет разрядность 32 (32 бита, или 4 байта на пиксел, что эквивалентно типу Integer. См. объявление типа TBig). Конструкция TBig(Scr^) позволяет адресовать эту память как массив пиксел. Чтобы получить доступ к пикселу нужно использовать индекс массива [x + y * SX].

Функция RGB. Это стандартная делфяцкая функция, не приспособленная для того что мы тут творим, а только для своего "родного" класс TCanvas и его цветовых кодов. В Windows при использовании 32-разрядных битмапов формат пиксела такой (начиная с первого байта):

            BBBBBBBB GGGGGGGG RRRRRRRR ********

В Delphi (то что ВСЕГДА возвращает функция RGB, при любой разрядности картинки):

            RRRRRRRR GGGGGGGG BBBBBBBB ********

Усматривается аналогия :) Все что нужно это просто перечислить аргументы функции в обратном порядке :))

            TBig(Scr^)[x + y * SX] := RGB(B, G, R);

B, G, R - соответственно значения интенсивности синего, зеленого, и красного цветов размером байт, т.е. [0..255].

Палитра 32-разрядным режимом не поддерживается, за нас думает Windows (вернее, понятия палитры в таком режиме вообще нет). Ну а нам остается это все юзать как надо +)))

Чтобы почистить виртуальный экран, нужно сделать так: ZeroMemory(Scr, SX * SY * 4);


procedure TfmMain.Timer1Timer(Sender: TObject);
var
  x, y: Integer;

begin
  // В цикле рисуется полная левота. Рисуйте тут свою левоту :)
  for x := 0 to SX - 1 do for y := 0 to SY - 1 do
    TBig(Scr^)[x + y * SX] := RGB(Random(256),Random(256),Random(256));

  // При желании, используем средства Delphi на объекте ScrBitmap типа TBitmap
  // в т.ч. можно нарисовать на нем другой Bitmap с помощью функции
  // ScrBitmap.Canvas.Draw(x,y,AnotherBitmap);
  // Чтобы текст выглядел красивее (без фона), раскомментируйте строки
  // SetBkMode(ScrBitmap.Canvas.Handle, TRANSPARENT);
  ScrBitmap.Canvas.Font.Size := 24;
  ScrBitmap.Canvas.TextOut(10, 10, 'Demo');
  // SetBkMode(ScrBitmap.Canvas.Handle, OPAQUE);

  // Нарисуемся
  pbDrawPaint(Self);
end;

end.

Пример программы на Delphi для создания простого приложения с графическим интерфейсом, которое может рисовать на компоненте TPaintBox без использования DirectX.

В этом примере есть несколько частей:

  1. Единица VisualForm содержит форму с несколькими компонентами: панель TPanel, компонент TPaintBox и несколько меток.
  2. Класс TfmMain наследуется от TForm и содержит несколько процедур:
    • CreateBitmap: создает битмап с помощью функции Windows API CreateDIBSection.
    • DeleteBitmap: освобождает память, выделенную в CreateBitmap.
    • RecreateBitmap: рекреates битмап при изменении размера формы.
    • FormCreate: инициализирует компонент TPaintBox и устанавливает его канвас для рисования на созданном битмапе.
    • FormDestroy: освобождает память, выделенную в FormCreate.
    • FormResize: рекреates битмап при изменении размера формы.
  3. Процедура pbDrawPaint вызывается каждый раз, когда компонент TPaintBox требует перерисовки, что происходит при вызове pbDraw.Canvas.Draw(0, 0, ScrBitmap).
  4. Событие таймера (Timer1Timer) имитирует рисование на компоненте TPaintBox, заполняя его случайными цветами с помощью массива TBig.

Этот пример демонстрирует использование Windows API для создания и манипуляции битмапами, а также рисования на компоненте TPaintBox в Delphi.

Некоторые улучшения можно было бы сделать:

  • Обработка ошибок: код предполагает, что все функции Windows API будут успешными. В реальности они могут неудачно выполниться, и должна быть реализована обработка ошибок.
  • Организация кода: класс TfmMain является quite большим и может быть разбит на более маленькие процедуры для лучшей поддержки.
  • Комментарии: в коде есть некоторые комментарии, но можно было бы добавить больше комментариев, чтобы объяснить логику некоторых частей программы.

В целом, это хороший пример использования Windows API для создания приложений с графическим интерфейсом в Delphi.

Пример быстрой работы с графикой в среде Windows без использования средств DirectX для создания и отображения битмапа на форме приложения.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Графика ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 13:26:04/0.0043129920959473/0