Графика в Delphi - примеры задач на построение графиков, а также компоненты для графики

Bitmap.Scanline для PixelFormat

Кто-то из Италии попросил меня пример использования pf1bit в изображениях (Bitmaps), я послал часто ответа из имеющихся заготовок, подумал, и добавил здесь другие детали для pf8bit и pf24bit.

Общее

Новое в Delphi 3 свойство scanline допускает быстрый доступ к отдельным пикселям, но необходимо указать с каким Bitmap.PixelFormat вы работаете, прежде чем сможете иметь доступ к пикселям.

Возможные PixelFormats включают:

1. pfDevice
2. pf1bit
3. pf4bit
4. pf8bit
5. pf15bit
6. pf16bit
7. pf24bit
8. pf32bit

pf24bit-изображения

Для pf24bit-изображений необходимо определить:

CONST
PixelCountMax = 32768;

TYPE
pRGBArray = ^TRGBArray;
TRGBArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;

Примечание: TRGBTriple определен в модуле Windows.PAS.

Для того, чтобы к существующему 24-битному изображению иметь доступ как к изображению, созданному с разрешением 3 байта на пиксел, сделайте следующее:


VAR
i : INTEGER;
j : INTEGER;
RowOriginal : pRGBArray;
RowProcessed: pRGBArray;
BEGIN
IF OriginalBitmap.PixelFormat <> pf24bit
THEN RAISE EImageProcessingError.Create(’GetImageSpace: ‘ +
‘Изображение должно быть 24-х битным.’);

{Шаг через каждую строчку изображения.}
FOR j := OriginalBitmap.Height-1 DOWNTO 0 DO
BEGIN
RowOriginal := pRGBArray(OriginalBitmap.Scanline[j]);
RowProcessed := pRGBArray(ProcessedBitmap.Scanline[j]);

FOR i := OriginalBitmap.Width-1 DOWNTO 0 DO
BEGIN

// Доступ к RGB-цветам отдельных пикселей должен осуществляться следующим образом:
// RowProcessed[i].rgbtRed := RowOriginal[i].rgbtRed;
// RowProcessed[i].rgbtGreen := RowOriginal[i].rgbtGreen;
// RowProcessed[i].rgbtBlue := RowOriginal[i].rgbtBlue;

END

END

pf8bit-изображения

Доступ к такому формату изображения легко получить, используя TByteArray (определен в SysUtils.PAS):

PByteArray = ^TByteArray;
TByteArray = array[0..32767] of Byte;

(Я думаю (но сам этого не пробовал), что вы сможете получить доступ к pf16bit-изображениям, используя следующие определения в SysUtils.PAS:

PWordArray = ^TWordArray;
TWordArray = array[0..16383] of Word;

Для того, чтобы обработать 8-битное (pf8bit) изображение, используйте конструктор подобный этому, который создает гистограмму изображения:

TYPE
THistogram = ARRAY[0..255] OF INTEGER;

VAR
Histogram: THistogram;
i : INTEGER;
j : INTEGER;
Row : pByteArray;


FOR i := Low(THistogram) TO High(THistogram) DO
Histogram[i] := 0;

IF Bitmap.PixelFormat = pf8bit
THEN BEGIN

FOR j := Bitmap.Height-1 DOWNTO 0 DO
BEGIN
Row := pByteArray(Bitmap.Scanline[j]);
FOR i := Bitmap.Width-1 DOWNTO 0 DO
BEGIN
INC (Histogram[Row[i]])
END
END

END

pf1bit-изображения

Доступ к pf8bit-изображениям осуществляется достаточно легко, с тех пор, как они стали использовать один байт на пиксель. Но вы можете сохранить много памяти, если вам необходим единственный бит на пиксель (как, например, с различными масками) в случае pf1bit-изображения.

Как и в случае с pf8bit-изображениями, используйте TByteArray для доступа к pf1bit-ным линиям чередования (Scanlines). Но для доступа к отдельным пикселям вам понадобиться работать с битами отдельного байта. Так, ширина линии чередования равна Bitmap.Width DIV 8 байт.

Нижеприведенный код показывает как можно создать шаблон 1-битного изображения: черный, белый, полоски, “g”, “стрелка” и случайный — опция “инвертировано” также доступна. (Надеюсь, технологию вы освоете без труда.)

Создайте форму с Image1: для TImage я использую одно изображение Image1 размером 256×256 и свойством Stretch := TRUE, чтобы отдельные пиксели было легко разглядеть. Кнопки Black, White и Stripes имеют свойство tags, c соответствующими значениями 0, 255, и 85 ($55 = 01010101 в двоичной системе исчисления), вызывающие при нажатии обработчик события ButtonStripesClick.

Кнопки “g” и “arrow” имеют собственные обработчики событий, позволяющие корректно распечатать тестовые изображения на принтере HP Laserjet.

“Random” случайным образом устанавливает биты в 1-битном изображении.

“Invert” меняет нули на единички и наоборот.

// Пример того, как использовать Bitmap.Scanline для PixelFormat=pf1Bit.
// По просьбе Mino Ballone из Италии.
//
// Авторское право (C) 1997, Earl F. Glynn, Overland Park, KS.
// Все права защищены.
// Может свободно использоваться для некоммерческих целей.

unit ScreenSingleBit;

interface

uses

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

type

TForm1 = class(TForm)
Image1: TImage;
ButtonBlack: TButton;
ButtonWhite: TButton;
ButtonStripes: TButton;
ButtonG: TButton;
ButtonArrow: TButton;
ButtonRandom: TButton;
ButtonInvert: TButton;
procedure ButtonStripesClick(Sender: TObject);
procedure ButtonGClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonRandomClick(Sender: TObject);
procedure ButtonInvertClick(Sender: TObject);
procedure ButtonArrowClick(Sender: TObject);
private
Bitmap: TBitmap;
{ Private declarations }
public
{ Public declarations }
end;

var

Form1: TForm1;

implementation

{$R *.DFM}

const

BitsPerPixel = 8;

procedure TForm1.ButtonStripesClick(Sender: TObject);

var
i: INTEGER;
j: INTEGER;
Row: pByteArray;
Value: BYTE;
begin

Value := (Sender as TButton).Tag;
// Value = $00 = 00000000 в двоичном исчислении для черного
// Value = $FF = 11111111 в двоичном исчислении для белого
// Value = $55 = 01010101 в двоичном исчислении для черных и белых полос

for j := 0 to Bitmap.Height - 1 do
begin
Row := pByteArray(Bitmap.Scanline[j]);
for i := 0 to (Bitmap.Width div BitsPerPixel) - 1 do
begin
Row[i] := Value
end
end;

Image1.Picture.Graphic := Bitmap
end;

procedure TForm1.ButtonGClick(Sender: TObject);

const
{Изображение “g” было адаптировано для печати на принтере
LaserJet IIP в соответствии с техническим руководством}

G: array[0..31, 0..3] of BYTE =
{ 0}(($00, $FC, $0F, $C0), {00000000 11111100 00001111 11000000}
{ 1}($07, $FF, $1F, $E0), {00000111 11111111 00011111 11100000}
{ 2}($0F, $FF, $9F, $C0), {00001111 11111111 10011111 11000000}
{ 3}($3F, $D7, $DE, $00), {00111111 11010111 11011110 00000000}
{ 4}($3E, $01, $FE, $00), {00111110 00000001 11111110 00000000}
{ 5}($7C, $00, $7E, $00), {01111100 00000000 01111110 00000000}
{ 6}($78, $00, $7E, $00), {01111000 00000000 01111110 00000000}
{ 7}($F0, $00, $3E, $00), {11110000 00000000 00111110 00000000}
{ 8}($F0, $00, $3E, $00), {11110000 00000000 00111110 00000000}
{ 9}($F0, $00, $1E, $00), {11110000 00000000 00011110 00000000}
{10}($F0, $00, $1E, $00), {11110000 00000000 00011110 00000000}
{11}($F0, $00, $1E, $00), {11110000 00000000 00011110 00000000}
{12}($F0, $00, $1E, $00), {11110000 00000000 00011110 00000000}
{13}($F0, $00, $3E, $00), {11110000 00000000 00111110 00000000}
{14}($78, $00, $3E, $00), {01111000 00000000 00111110 00000000}
{15}($78, $00, $3E, $00), {01111000 00000000 00111110 00000000}
{16}($78, $00, $7E, $00), {01111000 00000000 01111110 00000000}
{17}($3C, $00, $FE, $00), {00111100 00000000 11111110 00000000}
{18}($1F, $D7, $DE, $00), {00011111 11010111 11011110 00000000}
{19}($0F, $FF, $5E, $00), {00001111 11111111 10011110 00000000}
{20}($07, $FF, $1E, $00), {00000111 11111111 00011110 00000000}
{21}($00, $A8, $1E, $00), {00000000 10101000 00011110 00000000}
{22}($00, $00, $1E, $00), {00000000 00000000 00011110 00000000}
{23}($00, $00, $1E, $00), {00000000 00000000 00011110 00000000}
{24}($00, $00, $1E, $00), {00000000 00000000 00011110 00000000}
{25}($00, $00, $3E, $00), {00000000 00000000 00111110 00000000}
{26}($00, $00, $3C, $00), {00000000 00000000 00111100 00000000}
{27}($00, $00, $7C, $00), {00000000 00000000 01111100 00000000}
{28}($00, $01, $F8, $00), {00000000 00000001 11111000 00000000}
{29}($01, $FF, $F0, $00), {00000001 11111111 11110000 00000000}
{30}($03, $FF, $E0, $00), {00000011 11111111 11100000 00000000}
{31}($01, $FF, $80, $00)); {00000001 11111111 10000000 00000000}

var
i: INTEGER;
j: INTEGER;
Row: pByteArray;
begin

for j := 0 to Bitmap.Height - 1 do
begin
Row := pByteArray(Bitmap.Scanline[j]);
for i := 0 to (Bitmap.Width div BitsPerPixel) - 1 do
begin
Row[i] := G[j, i]
end
end;

Image1.Picture.Graphic := Bitmap
end;

procedure TForm1.ButtonArrowClick(Sender: TObject);

const
{Изображение “стрелка” было адаптировано для печати на принтере
LaserJet IIP в соответствии с техническим руководством}

Arrow: array[0..31, 0..3] of BYTE =
{ 0}(($00, $00, $80, $00), {00000000 00000000 10000000 00000000}
{ 1}($00, $00, $C0, $00), {00000000 00000000 11000000 00000000}
{ 2}($00, $00, $E0, $00), {00000000 00000000 11100000 00000000}
{ 3}($00, $00, $F0, $00), {00000000 00000000 11110000 00000000}
{ 4}($00, $00, $F8, $00), {00000000 00000000 11111000 00000000}
{ 5}($00, $00, $FC, $00), {00000000 00000000 11111100 00000000}
{ 6}($00, $00, $FE, $00), {00000000 00000000 11111110 00000000}
{ 7}($00, $00, $FF, $00), {00000000 00000000 11111111 00000000}
{ 8}($00, $00, $FF, $80), {00000000 00000000 11111111 10000000}
{ 9}($FF, $FF, $FF, $C0), {11111111 11111111 11111111 11000000}
{10}($FF, $FF, $FF, $E0), {11111111 11111111 11111111 11100000}
{11}($FF, $FF, $FF, $F0), {11111111 11111111 11111111 11110000}
{12}($FF, $FF, $FF, $F8), {11111111 11111111 11111111 11111000}
{13}($FF, $FF, $FF, $FC), {11111111 11111111 11111111 11111100}
{14}($FF, $FF, $FF, $FE), {11111111 11111111 11111111 11111110}
{15}($FF, $FF, $FF, $FF), {11111111 11111111 11111111 11111111}
{16}($FF, $FF, $FF, $FF), {11111111 11111111 11111111 11111111}
{17}($FF, $FF, $FF, $FE), {11111111 11111111 11111111 11111110}
{18}($FF, $FF, $FF, $FC), {11111111 11111111 11111111 11111100}
{19}($FF, $FF, $FF, $F8), {11111111 11111111 11111111 11111000}
{20}($FF, $FF, $FF, $F0), {11111111 11111111 11111111 11110000}
{21}($FF, $FF, $FF, $E0), {11111111 11111111 11111111 11100000}
{22}($FF, $FF, $FF, $C0), {11111111 11111111 11111111 11000000}
{23}($00, $00, $FF, $80), {00000000 00000000 11111111 10000000}
{24}($00, $00, $FF, $00), {00000000 00000000 11111111 00000000}
{25}($00, $00, $FE, $00), {00000000 00000000 11111110 00000000}
{26}($00, $00, $FC, $00), {00000000 00000000 11111100 00000000}
{27}($00, $00, $F8, $00), {00000000 00000000 11111000 00000000}
{28}($00, $00, $F0, $00), {00000000 00000000 11110000 00000000}
{29}($00, $00, $E0, $00), {00000000 00000000 11100000 00000000}
{30}($00, $00, $C0, $00), {00000000 00000000 11000000 00000000}
{31}($00, $00, $80, $00)); {00000000 00000000 10000000 00000000}

var
i: INTEGER;
j: INTEGER;
Row: pByteArray;
begin

for j := 0 to Bitmap.Height - 1 do
begin
Row := pByteArray(Bitmap.Scanline[j]);
for i := 0 to (Bitmap.Width div BitsPerPixel) - 1 do
begin
Row[i] := arrow[j, i]
end
end;

Image1.Picture.Graphic := Bitmap
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

Bitmap := TBitmap.Create;
with Bitmap do
begin
Width := 32;
Height := 32;
PixelFormat := pf1bit
end;
Image1.Picture.Graphic := Bitmap
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin

Bitmap.Free
end;

procedure TForm1.ButtonRandomClick(Sender: TObject);

var
i: INTEGER;
j: INTEGER;
Row: pByteArray;
begin

for j := 0 to Bitmap.Height - 1 do
begin
Row := pByteArray(Bitmap.Scanline[j]);
for i := 0 to (Bitmap.Width div BitsPerPixel) - 1 do
begin
Row[i] := Random(256)
end
end;

Image1.Picture.Graphic := Bitmap
end;

procedure TForm1.ButtonInvertClick(Sender: TObject);

var
i: INTEGER;
j: INTEGER;
Row: pByteArray;
begin

for j := 0 to Bitmap.Height - 1 do
begin
Row := pByteArray(Bitmap.Scanline[j]);
for i := 0 to (Bitmap.Width div BitsPerPixel) - 1 do
begin
Row[i] := not Row[i]
end
end;

Image1.Picture.Graphic := Bitmap
end;

end.

Powered WP Ъ скачать delphi, delphi 7, скачать delphi 7, delphi файлы, delphi, компоненты, delphi 2009, delphi программы, delphi бесплатно, delphi скачать, бесплатно работа delphi, delphi создание, delphi строки, программирования delphi, borland delphi, delphi формы