• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

DelphiTBitmapScanline

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

使用Dephi进行图像处理可以有多种方法,最常用的应该算是TBitmap,它提供方便的图像存取能力,结合Canvas可进行画线、画圆、图像拷贝等操作。
不过在进行大量的图像处理操作时,为了获得更高的速度,我们希望能够直接对图像缓冲区进行读写。查阅Dephi的帮助手册没有发现直接取得整个图像缓冲区的功能,
但提供的ScanLine属性可以取得指定行图像数据的指针,比较接近我们的要求,先看看ScanLine的描述:

property ScanLine[Row: Integer]: Pointer; Provides indexed access to each line of pixels.
ScanLine is used only with DIBs (Device Independent Bitmaps) for image editing tools that do low-level pixel work.
 

  tagBITMAPINFOHEADER = record
    biSize: DWORD;
    biWidth: Longint;
    biHeight: Longint;
    biPlanes: Word;
    biBitCount: Word;
    biCompression: DWORD;
    biSizeImage: DWORD;
    biXPelsPerMeter: Longint;
    biYPelsPerMeter: Longint;
    biClrUsed: DWORD;
    biClrImportant: DWORD;
  end;

DWORD biSize;//指定结构需要的比特数。这个值不包含在结构的结尾被添上的颜色表或者颜色盒的大小。
LONG   biWidth;//指定位图的像素宽度
LONG   biHeight;//指定位图的高度。单位是像素
biPlanes //Specifies the number of planes for the target device. This value must be set to 1.
biBitCount //指定每像素的比特数(bpp)。0 - JPEG or PNG, 1 - Monochrome
biCompression //对于压缩的视频和YUV格式,该数字是一个FOURCC代码。对于没有压缩的RGB,这个值是BI_RGB
DWORD biSizeImage;//位图的大小,单位是比特。对于没有压缩的RGB位图,该数值可以被设置为0
LONG   biXPelsPerMeter;//规定了该位图的目标设备的水平模式,单位是像素每米
LONG   biYPelsPerMeter;//规定了该位图的目标设备的垂直模式,单位是像素每米
DWORD biClrUsed;//规定了颜色表中的颜色点数,它们被位图使用
DWORD biClrImportant;//规定了在位图中比较重要的颜色点数,如果值为0,那么所有的颜色都是重要的。

biWidth

The width of the bitmap, in pixels.
If biCompression is BI_JPEG or BI_PNG, the biWidth member specifies the width of the decompressed JPEG or PNG image file, respectively.

biHeight

The height of the bitmap, in pixels.
If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner.
If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.
If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed.

If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies the height of the decompressed JPEG or PNG image file, respectively.

BI_RGB
An uncompressed format.

BI_BITFIELDS
Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks
that specify the red, green, and blue components, respectively, of each pixel.
This is valid when used with 16- and 32-bpp bitmaps.

 

function BytesPerScanline(PixelsPerScanline, BitsPerPixel, Alignment: Longint): Longint;
begin
  Dec(Alignment);
  Result := ((PixelsPerScanline * BitsPerPixel) + Alignment) and not Alignment;
  Result := Result div 8;
end;

  


function
TBitmap.GetScanLine(Row: Integer): Pointer; begin Changing(Self); with FImage.FDIB, dsbm, dsbmih do begin if (Row < 0) or (Row >= bmHeight) then InvalidOperation(@SScanLine); DIBNeeded; GDIFlush; if biHeight > 0 then // bottom-up DIB Row := biHeight - Row - 1
else
    Row := Row; // top-down DIB 
Result :
= PByte(bmBits) + Row * BytesPerScanline(biWidth, biBitCount, 32); end; end;

  

procedure TForm1.Button1Click( Sender : TObject );
var
  BitMap : TBitmap;
  S : String;
begin
  BitMap := TBitmap.Create;
  try
    BitMap.PixelFormat := pf24bit; // 24位色,每像素点3个字节 -- 首先设置 PixelFormat 否则出错 !
    BitMap.Width := 1000;
    BitMap.Height := 2;       // BitMap.Height := -2; -- Top-Down DIB [ ScanLine[0] -- First Row ]   
    FmtStr( S, 'ScanLine[0]:%8x'#13'ScanLine[1]:%8x'#13'ScanLine[1]-ScanLine[0]:%d', 
    [ Integer( BitMap.ScanLine[ 0 ] ), Integer( BitMap.ScanLine[ 1 ] ), Integer( BitMap.ScanLine[ 1 ] ) - Integer( BitMap.ScanLine[ 0 ] ) ] );
    MessageBox( Handle, PChar( S ), 'ScanLine', MB_OK );
  finally
    if Assigned( BitMap ) then
      FreeAndNil( BitMap );
  end;
end
ScanLine[0]: E90BB8
ScanLine[1]: E90000
ScanLine[1]-ScanLine[0]:-3000

让我们再看看ScanLine[0]、ScanLine[1]的关系, ScanLine[0]与ScanLine[1]之间相差3000=1000像素宽×3字节这很容易理解,但为什么是负数呢?
因为BMP图像数据是“按行存放,每行按双字对齐,行按倒序方式存放”的,也就是说屏幕显示的第一行存放在最后,
屏幕显示的最后一行存放在前面,所以用ACDSee等看图软件查看尺寸较大的位图时先从下部开始显示就是这个道理。
从上面的结果可以看出TBitmap的图像数据在内存中是按行倒序连续存放的,
通过TBitmap.ScanLine[TBitmap.Height-1]可以取得首地址即图像缓冲区地址 

Memory : Bottom-Up DIB : origin is the lower-left corner
  ScanLine[H-1] \    /  *****************
  ScanLine[H-2]  \  /   *****************
                  \/
  ScanLine[1]     /\    *****************
  ScanLine[0]   /   \   *****************

Memory :  Top-Down DIB : origin is the upper-left corner.
  ScanLine[0]   -----   *****************
  ScanLine[1]   -----   *****************
  
  ScanLine[H-2] -----   *****************
  ScanLine[H-1] -----   *****************

http://msdn.microsoft.com/en-us/library/windows/desktop/dd407212(v=vs.85).aspx

If you are new to graphics programming, you might expect that a bitmap would be arranged in memory
so that the top row of the image appeared at the start of the buffer, followed by the next row, and so forth.
However, this is not necessarily the case. In Windows, device-independent bitmaps (DIBs) can be placed in memory
in two different orientations, bottom-up and top-down.

In a bottom-up DIB, the image buffer starts with the bottom row of pixels, followed by the next row up, and so forth.
The top row of the image is the last row in the buffer.
Therefore, the first byte in memory is the bottom-left pixel of the image.
In GDI, all DIBs are bottom-up. The following diagram shows the physical layout of a bottom-up DIB.

 

In a top-down DIB, the order of the rows is reversed.
The top row of the image is the first row in memory, followed by the next row down.
The bottom row of the image is the last row in the buffer.
With a top-down DIB, the first byte in memory is the top-left pixel of the image.
DirectDraw uses top-down DIBs. The following diagram shows the physical layout of a top-down DIB:

 

For RGB DIBs, the image orientation is indicated by the biHeight member of the BITMAPINFOHEADER structure.
If biHeight is positive, the image is bottom-up.
If biHeight is negative, the image is top-down.

DIBs in YUV formats are always top-down, and the sign of the biHeight member is ignored.
Decoders should offer YUV formats with positive biHeight, but they should also accept YUV formats
with negative biHeight and ignore the sign.

Also, any DIB type that uses a FOURCC in the biCompression member, should express its biHeight as a positive number no matter
what its orientation is, since theFOURCC itself identifies a compression scheme whose image orientation should be
understood by any compatible filter.

 

function CreateDIB_TopDown( nWidth, nHeight : Integer ) : HBITMAP;
var
  hbm : HBITMAP;
  hdcMem : HDC;
  bmi : BITMAPINFO;
pvBits : LPBYTE; // ScanLine[0]
begin hdcMem := CreateCompatibleDC( 0 ); if hdcMem > 0 then begin ZeroMemory( @( bmi.bmiHeader ), sizeof( BITMAPINFOHEADER ) ); bmi.bmiHeader.biSize := sizeof( BITMAPINFOHEADER ); bmi.bmiHeader.biWidth := nWidth; bmi.bmiHeader.biHeight := -nHeight; // Use a top-down DIB bmi.bmiHeader.biPlanes := 1; bmi.bmiHeader.biBitCount := 32; hbm := CreateDIBSection( hdcMem, bmi, DIB_RGB_COLORS, Pointer( pvBits), 0, 0 ); if ( hbm > 0 ) then begin// Fill in the pixels of the bitmap end; DeleteDC( hdcMem ); end; Result := hbm; end;

Bitmap data area 
This 
is a byte stream that describes the pixels of the image (this may or may not be in compressed form) in 1-, 4-, 8-, 16-, or 24-bit format.
The data is in line-by-line order, but it may be upside-down so that the first line of data is the last line of the image
.
You can detect this by looking at the sign of 
biHeight — a positive sign means the bitmap is upside-down,
and a negative sign means the bitmap is normal.

 

最后补充说明一下:

  1. Bitmap图像缓冲区是双节对齐的,如果把例1中的图像宽度改为999,一个像素行还是占3000个字节。
  2. 目前Bitmap.PixelFormat有pfDevice、pf1bit、pf4bit、pf8bit、pf15bit、pf16bit、pf24bit、pf32bit、pfCustom共9种,
    不同格式每个像素所占字节数不同,其中pf4bit和pf8bit格式的图像缓冲区保存的为颜色索引号,真正的颜色值在调色板中,
    pf15bit、pf16bit格式中RGB所占的位数(Bit)不一定是等长的。

通过直接对图像缓冲区的读写将图像淡出到黑色

procedure TForm1.Button1Click( Sender : TObject );
const
  FADEOUT_STEP = 24; // 淡出衰减值
  FIX_WIDTH = 320;
  FIX_HEIGHT = 200;
var
  BitMap : TBitmap;
  hWinDC : HDC;
  flagAgein : Boolean;
  lpBuffer : PByte; // 图像缓冲区指针
begin
  BitMap := TBitmap.Create;
  if not Assigned( BitMap ) then
    Exit;
  try
    // 设置位图格式、宽度、高度
    BitMap.PixelFormat := pf24bit;
    BitMap.Width := FIX_WIDTH;
    BitMap.Height := FIX_HEIGHT;
    // 设置Form的宽充、高度,便于显示结果
    Button1.Visible := false;
    ClientWidth := FIX_WIDTH;
    ClientHeight := FIX_HEIGHT;
    // 拷贝图像到Bitmap中
    hWinDC := GetDC( 0 );
    if ( hWinDC <> NULL ) then
      BitBlt( BitMap.Canvas.Handle, 0, 0, FIX_WIDTH, FIX_HEIGHT, hWinDC, 0, 0, SRCCOPY )
    else
      BitBlt( BitMap.Canvas.Handle, 0, 0, FIX_WIDTH, FIX_HEIGHT, Canvas.Handle, 0, 0, SRCCOPY );
    repeat
      flagAgein := false;
      lpBuffer := BitMap.ScanLine[ FIX_HEIGHT - 1 ]; 
// 取得图像缓冲区首地址 Integer(BitMap.ScanLine[0]) + FIX_WIDTH*3 为图像缓冲区结束地址 while Integer( lpBuffer ) < Integer( BitMap.ScanLine[ 0 ] ) + FIX_WIDTH * 3 do begin if lpBuffer^ > FADEOUT_STEP then begin Dec( lpBuffer^, FADEOUT_STEP ); flagAgein := true; end else lpBuffer^ := 0; Inc( lpBuffer ); Application.ProcessMessages; end; Canvas.Draw( 0, 0, BitMap ); until ( not flagAgein ); MessageBox( Handle, 'Done', 'Fadeout', MB_OK ); finally if Assigned( BitMap ) then FreeAndNil( BitMap ); Button1.Visible := true; end; end;

 

 

http://www.esanu.name/delphi/Multimedia/Graphics/Bitmap.Scanline%20for%20PixelFormat=pf1bit,%20pf8bit,%20pf24bit.html

Bitmap.Scanline for PixelFormat=pf1bit, pf8bit, pf24bit

Since someone from Italy asked me for an example of using pf1bit Bitmaps, I thought I would post part of my response and add other details for pf8bit and pf24bit here in case others were wondering.

Background

The new Delphi 3 scanline property allows quick access to individual pixels, but you must know what Bitmap.PixelFormat you're working with before you can access the pixels.

Possible PixelFormats include:

pfDevice pf1bit pf4bit pf8bit pf15bit pf16bit pf24bit pf32bit 

For pf24bit bitmaps, I define (I wish Borland would)

CONST
  PixelCountMax = 32768;

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

Note: TRGBTriple is defined in the Windows.PAS unit.

To step through a 24-bit bitmap and while creating a new one and access the 3-bytes-per-pixel data, use a construct like the following

VAR
  i : INTEGER;
  j : INTEGER;
  RowOriginal : pRGBArray;
  RowProcessed : pRGBArray;
BEGIN
  IF OriginalBitmap.PixelFormat <> pf24bit THEN
    RAISE EImageProcessingError.Create( 'GetImageSpace: ' + 'Bitmap must be 24-bit color.' );

  { Step through each row of image. }
  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
      // Access individual color RGB color planes with references like:
      // RowProcessed[i].rgbtRed := RowOriginal[i].rgbtRed;
      // RowProcessed[i].rgbtGreen := RowOriginal[i].rgbtGreen;
      // RowProcessed[i].rgbtBlue := RowOriginal[i].rgbtBlue;
    END
  END
END;

pf8bit Bitmaps

Access to these byte-per-pixel bitmaps is easy using the TByteArray (defined in SysUtils.PAS)

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

I suppose, but I've never tried it, you could access pf16bit Bitmaps using the following defined in SysUtils.PAS:

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

To process an 8-bit (pf8bit) bitmap, use a construct like the following that constructs a histogram of such a bitmap:

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 Bitmaps

Accessing pf8bit bitmaps is easy since they are one byte per pixel.
But you can save a lot of memory if you only need a single bit per pixel (such as with various masks), if you use pf1bit Bitmaps.
As with pf8bit bitmaps, use a TByteArray to access pf1bit Scanlines.
But you will need to perform bit operations on the bytes to access the various pixels.
Also, the width of the Scanline is Bitmap.Width DIV 8 bytes.
 

The following code shows how to create the following kinds of 1-bit bitmaps:
black, white, stripes, "g", "arrow" and random -- an "invert" option is also available.
(Send me an E-mail if you'd like the complete working source code including the form.) 

Create a form with an Image1: TImage on it -- I used 1 256x256 Image1 with Stretch := TRUE to see the individual pixels more easily.
The buttons Black, White and Stripes have tags of 0, 255, and 85 ($55 = 01010101 binary) that call ButtonStripesClick when selected.
Buttons "g" and "arrow" call separate event handlers to draw these bitmaps taken form HP Laserjet examples.
"Random" just randomly sets bits on in the 1-bit bitmaps.
"Invert" changes all the 0s to 1's and vice versa.

// Example of how to use Bitmap.Scanline for PixelFormat=pf1Bit.
// Requested by Mino Ballone from Italy.
//
// Copyright (C) 1997, Earl F. Glynn, Overland Park, KS. All rights reserved.
// May be freely used for non-commerical purposes.

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 binary for black
  // Value = $FF = 11111111 binary for white
  // Value = $55 = 01010101 binary for black & white stripes

  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
  { The "g" bitmap was adapted from the LaserJet IIP Printer Tech Ref
    Manual }
  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
  { The "arrow" bitmap was adapted from the LaserJet IIP Printer Tech Ref Manual }
  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 }
    { 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi指针大全(光看不练是学不会的)发布时间:2022-07-18
下一篇:
delphi可变记录(2)发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap