Общее
Новое в Delphi 3 свойство scanline допускает быстрый доступ к отдельным пикселям, но необходимо указать с каким Bitmap.PixelFormat вы работаете, прежде чем сможете иметь доступ к пикселям.
Возможные PixelFormats включают:
Для pf24bit-изображений необходимо определить:
CONSTPixelCountMax = 32768; TYPEpRGBArray = ^TRGBArray;TRGBArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple; |
Примечание: TRGBTriple определен в модуле Windows.PAS.
Для того, чтобы к существующему 24-битному изображению иметь доступ как к изображению, созданному с разрешением 3 байта на пиксел, сделайте следующее:
...VARi : INTEGER;j : INTEGER;RowOriginal : pRGBArray;RowProcessed: pRGBArray;BEGINIF OriginalBitmap.PixelFormat <> pf24bitTHEN RAISE EImageProcessingError.Create('GetImageSpace: ' +'Изображение должно быть 24-х битным.'); {Шаг через каждую строчку изображения.}FOR j := OriginalBitmap.Height-1 DOWNTO 0 DOBEGINRowOriginal := pRGBArray(OriginalBitmap.Scanline[j]);RowProcessed := pRGBArray(ProcessedBitmap.Scanline[j]); FOR i := OriginalBitmap.Width-1 DOWNTO 0 DOBEGIN // Доступ к 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; |
TYPETHistogram = ARRAY[0..255] OF INTEGER;... VARHistogram: THistogram;i : INTEGER;j : INTEGER;Row : pByteArray; ...FOR i := Low(THistogram) TO High(THistogram) DOHistogram[i] := 0; IF Bitmap.PixelFormat = pf8bitTHEN BEGIN FOR j := Bitmap.Height-1 DOWNTO 0 DOBEGINRow := pByteArray(Bitmap.Scanline[j]);FOR i := Bitmap.Width-1 DOWNTO 0 DOBEGININC (Histogram[Row[i]])ENDEND END... |
// Пример того, как использовать 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);privateBitmap: TBitmap;{ Private declarations }public{ Public declarations }end; var Form1: TForm1; implementation {$R *.DFM} CONST BitsPerPixel = 8; procedure TForm1.ButtonStripesClick(Sender: TObject); VARi : 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 DOBEGINRow := pByteArray(Bitmap.Scanline[j]);FOR i := 0 TO (Bitmap.Width DIV BitsPerPixel)-1 DOBEGINRow[i] := ValueENDEND; Image1.Picture.Graphic := Bitmapend; 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} VARi : INTEGER;j : INTEGER;Row: pByteArray;begin FOR j := 0 TO Bitmap.Height-1 DOBEGINRow := pByteArray(Bitmap.Scanline[j]);FOR i := 0 TO (Bitmap.Width DIV BitsPerPixel)-1 DOBEGINRow[i] := G[j,i]ENDEND; Image1.Picture.Graphic := Bitmapend; 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} VARi : INTEGER;j : INTEGER;Row: pByteArray;begin FOR j := 0 TO Bitmap.Height-1 DOBEGINRow := pByteArray(Bitmap.Scanline[j]);FOR i := 0 TO (Bitmap.Width DIV BitsPerPixel)-1 DOBEGINRow[i] := arrow[j,i]ENDEND; Image1.Picture.Graphic := Bitmapend; procedure TForm1.FormCreate(Sender: TObject); begin Bitmap := TBitmap.Create;WITH Bitmap DOBEGINWidth := 32;Height := 32;PixelFormat := pf1bitEND;Image1.Picture.Graphic := Bitmapend; procedure TForm1.FormDestroy(Sender: TObject); begin Bitmap.Freeend; procedure TForm1.ButtonRandomClick(Sender: TObject); VARi : INTEGER;j : INTEGER;Row: pByteArray;begin FOR j := 0 TO Bitmap.Height-1 DOBEGINRow := pByteArray(Bitmap.Scanline[j]);FOR i := 0 TO (Bitmap.Width DIV BitsPerPixel)-1 DOBEGINRow[i] := Random(256)ENDEND; Image1.Picture.Graphic := Bitmapend; procedure TForm1.ButtonInvertClick(Sender: TObject); VARi : INTEGER;j : INTEGER;Row: pByteArray;begin FOR j := 0 TO Bitmap.Height-1 DOBEGINRow := pByteArray(Bitmap.Scanline[j]);FOR i := 0 TO (Bitmap.Width DIV BitsPerPixel)-1 DOBEGINRow[i] := NOT Row[i]ENDEND; Image1.Picture.Graphic := Bitmapend; end. |