Недавно добавленные исходники

•  TDictionary Custom Sort  3 225

•  Fast Watermark Sources  2 991

•  3D Designer  4 750

•  Sik Screen Capture  3 259

•  Patch Maker  3 467

•  Айболит (remote control)  3 528

•  ListBox Drag & Drop  2 904

•  Доска для игры Реверси  80 780

•  Графические эффекты  3 843

•  Рисование по маске  3 171

•  Перетаскивание изображений  2 544

•  Canvas Drawing  2 672

•  Рисование Луны  2 500

•  Поворот изображения  2 092

•  Рисование стержней  2 120

•  Paint on Shape  1 525

•  Генератор кроссвордов  2 183

•  Головоломка Paletto  1 730

•  Теорема Монжа об окружностях  2 158

•  Пазл Numbrix  1 649

•  Заборы и коммивояжеры  2 016

•  Игра HIP  1 262

•  Игра Go (Го)  1 200

•  Симулятор лифта  1 422

•  Программа укладки плитки  1 177

•  Генератор лабиринта  1 512

•  Проверка числового ввода  1 297

•  HEX View  1 466

•  Физический маятник  1 322

•  Задача коммивояжера  1 357

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

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 размером 256x256 и свойством 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.





Похожие по теме исходники

Bitmap Sharpen Filter

Simple Bitmap Rotation

Bitmap 32Bit Demo

Thread Bitmap (pencil drawings)

 

Snow ScanLine

Animation ScanLine

Scanline Demo

Нейросеть для распознавания образов

 

Механизм станка качалки для нефти

Весы для взвешивания

Кувшины для воды

Доска для игры Реверси

 



Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте