呵呵,用ScanLine的效率要高些。

解决方案 »

  1.   

    不能代替,除非Bitmap是32bit,至少是24bit的。因为Pixels属性是32位TColor的,而Bitmap内部不见得是True Color,在通过Pixels设置时,会自动调整,而直接操作Scanline则这个调整需要由用户来完成。因此,当需要使用Scanline时,最好建立TureColor的Bitmap。
      

  2.   

    to goodhope:我就是针对24bit的图像进行操纵啊!!你能告诉我吗???反正速度快就行了,用pixels速度太慢了!
      

  3.   

    针对24bit的Bitmap操作,你需要定义新的数据结构,一种3BYTE的类型。这种操作会使操作变得复杂,因此如果Bitmap占用的空间不大的话建议使用32bit的格式。另外,ScanLine虽然效率要远胜于Pixels,但是,也还是比较花时间。因此,频繁操作时,最好建一个指针数组作为中介。在Windows中,Bitmap的每个TrueColor点的数据中0~7的8bit代表Blue分量,8~15的8Bit代表Green分量,16~23的8bit代表Red分量,24~31的8bit代表Alpha分量。Alpha现在一般操作用不着,多用于游戏。24bit和32bit颜色结构如下:
    T24bitColor = packed record
    Blue, Green, Red: BYTE;
    end;T32bitColor = packed record
    Blue, Green, Red, Alpha: BYTE;
    end;P24bitColors = ^T24bitColors;
    T24bitColors = array [0..MaxListSize] of T24bitColor;P32bitColors = ^T32bitColors;
    T32bitColors = array [0..MaxListSize] of T32bitColor;类似的还可以定义15bit和16bit高彩的数据结构。对于32bit的格式还可以定义一个变体结构,以简化赋值操作。
    TMyColor = record
    case Integer of
    0: (Value: Cardinal);
    1: (Color: TColor);
    2: (bitColor: T32bitColor);
    end;数组也可类似的改为
    PMyColor = ^TMyColors;
    TMyColors = array [0..MaxListSize] of TMyColor;使用时可以如下:
    var
    ix, iy, iCount: Integer;
    ScanLines: array of P32bitColors;
    AColor: T32bitColor;
    begin SetLength(ScanLines, Bitmap.Height);
    for iCount := 0 to Bitmap.Height - 1 do
    ScanLines[iCount] := Bitmap.ScanLine[iCount]; ... ... ScanLines[iy][ix] := AColor.bitColor;end;
      

  4.   

    to GoodHope:先谢谢你!但是我还是有些不懂?以下的代码我怎么也通不过?也不能达到我的目的?如果你有时间,请给出用ScanLine取得每象素的RGB值!!! 谢谢!
    procedure TForm1.Button1Click(Sender: TObject);
    var
        ix, iy, iCount: Integer;
        ScanLines: array of P32bitColors;
        AColor: T32bitColor;
    begin    SetLength(ScanLines, img.picture.Bitmap.Height);
        for iCount := 0 to img.picture.Bitmap.Height - 1 do
            ScanLines[iCount] := img.picture.Bitmap.ScanLine[iCount];
        ScanLines[iy][ix]:=acolor ;
    end;
      

  5.   

    1,你需要在type部分加上P32bitColors的相关定义;
    2,确认Bitmap的PixelFormat是pf32bit;
    3,是aColor.bitColor := ScanLines[0][0];而不是aColor := ScanLines[0][0];
    这样aColor.bitColor.Red、aColor.bitColor.Green、aColor.bitColor.Blue就分别代表红、绿、蓝3个分量。
      

  6.   

    你说的aColor是T32bitColor类型
    应该aColor := ScanLines[0][0];
    但是运行后会出现错误,我试过
      

  7.   

    哦,我给出的代码有点问题。在var部分应该是:
    AColor: TMyColor;
    当然这只是我的习惯。用
    AColor: T32bitColor;
    也可以。运行错误是不是因为你用Image读入了其他格式的图像,比如JPG的?这样的情况下,TBitmap里面是没有数据的。因为Bitmap代表的是没有压缩的光栅数据。如果要通过Scanline操作,需要把它Draw到新的Bitmap上,从新的上读取。
      

  8.   

    P : PRGBTriple;
    for y := 0 to BitMap.height -1 do
          begin
            P := BitMap.ScanLine[y];
            for x := 0 to BitMap.width -1 do
            begin
              //访问像素 RGB
              //P^.rgbtBlue
              //P^.rgbtGreen
              //P^.rgbtRed
              inc(P);//指向下一个像素
            end;
          end;