Bitmap如何用scanline读取每一个像素的颜色(TColor型),并保存到一个数组中???

解决方案 »

  1.   

    var
            x,y : Integer;
            BitMap1,BitMap2 : TBitMap;
            P : PByteArray;
            mArray: array of byte;
            mRect: TRect;
    begin
            BitMap1 := TBitMap.create;
            BitMap2 := TBitMap.Create;
            try
                    BitMap1.LoadFromFile('d:\test.bmp');                SetLength(mArray,BitMap1.Height * BitMap1.Width * 4);
                    //从bitmap中取至数组
                    for y := 0 to BitMap1.Height -1 do
                    begin
                            P := BitMap1.ScanLine[y];
                            for x := 0 to (BitMap1.Width -1)*4 do
                                    mArray[y*BitMap1.Width*4+x] := P[x];
                    end;                //从数组中写到另一bitmap
                    BitMap2.Height := BitMap1.Height;
                    BitMap2.Width := BitMap1.Width;
                    BitMap2.PixelFormat := BitMap1.PixelFormat;
                    for y := 0 to BitMap1.Height -1 do
                    begin
                            p := BitMap2.ScanLine[y];
                            for x := 0 to (BitMap2.Width -1)*4 do
                                    p[x] := mArray[y*BitMap1.Width*4+x];
                    end;                //输出原图至窗口的左上角
                    Canvas.CopyRect(BitMap1.Canvas.ClipRect,BitMap1.Canvas,BitMap1.Canvas.ClipRect);                //在原图下方输出生成图
                    mRect := BitMap2.Canvas.ClipRect;
                    mRect.Top := mRect.Top + BitMap1.Height;
                    mRect.Bottom := mRect.Bottom + BitMap1.Height;
                    Canvas.CopyRect(mRect,BitMap2.Canvas,BitMap2.Canvas.ClipRect);
            finally
                    BitMap1.Free;
                    BitMap2.Free;
            end;
    end;
      

  2.   

    我用的这个图的PixelFormat是pf32bit,所以程序里面横向部分的处理是×4的。
      

  3.   

    const PixelCountMax=10000;
    type
      PRGBArray  = ^TRGBArray;
      TRGBArray  = array[0..PixelCountMax-1] of TRGBTriple;
    var Bitmap:TBitmap;
        p : PRGBArray;
        x, y: integer;
        c : array of array of TColor;
    begin
      Bitmap := TBitmap.Create;
      try
      Bitmap.LoadFromFile('c:\1.bmp');
      SetLength(c, Bitmap.Width, Bitmap.Height);
      Bitmap.PixelFormat :=  pf24bit;
      for y:=0 to Bitmap.Height-1 do
       begin
         p := PRGBArray(Bitmap.ScanLine[y]);
         for x:=0 to Bitmap.Width-1  do
         begin
           //保存在数组c内
           c[x,y]:= RGB(p[x].rgbtRed,p[x].rgbtGreen,p[x].rgbtBlue);
         end;
       end;
      for x:=0 to bitmap.Width-1 do
        for y:=0 to Bitmap.Height-1 do
          Canvas.Pixels[x, y]:=c[x,y];
      finally
        Bitmap.Free;
     end;
    end;
      

  4.   

    读文件数据到  BMP 中 即使2G图片显示屏幕大小只须 0.02s //从指定的文件中读取一块图像 位置在 Px,Py(左下角坐标) 宽度 高度 由 ABMP 确定
    Procedure ReadBMPData(BMPFile:String; ABMP:TBitMap; Px,Py:LongInt);
    Var AFile:File Of Byte;
        FileHead:TBITMAPFILEHEADER;
        InfoHead:TBITMAPINFOHEADER;
        BytesPerLine:LongInt;    Bw,Bh:Integer;             //源图像大小
        W,H:Integer;               //目标图像大小
        X1,Y1,X2,Y2:Integer;       //复制区域    I:Integer;
    Begin
         If ABMP=Nil Then Exit;
         If Not FileExists(BMPFile) Then Exit;     {$I-}
         AssignFile(AFile,BMPFile);
         FileMode := 0;
         Reset(AFile);     BlockRead(AFile,FileHead,SizeOf(TBITMAPFILEHEADER));
         BlockRead(AFile,InfoHead,SizeOf(TBITMAPINFOHEADER));
         If ((InfoHead.biBitCount<>24) OR (InfoHead.biCompression<>0)) Then
         Begin
              //必须是 24 位 非压缩文件格式
              CloseFile(AFile);
              Exit;
         End;     //每条扫描线数据长度
         BytesPerLine:=(InfoHead.biWidth* InfoHead.biBitCount+31) Div 8;
         BytesPerLine:=(BytesPerLine Div 4)*4;     //目标相关信息
         Bw:=InfoHead.biWidth; Bh:=InfoHead.biHeight;
         W:=ABmp.Width; H:=ABmp.Height;     //坐标变换
         X1:=Px;   If X1<0 Then X1:=0 Else If X1>Bw-1 Then X1:=Bw-1;
         Y1:=Py;   If Y1<0 Then Y1:=0 Else If Y1>Bh-1 Then Y1:=Bh-1;
         X2:=Px+W-1; If X2<0 Then X2:=0 Else If X2>Bw-1 Then X2:=Bw-1;
         Y2:=Py+H-1; If Y2<0 Then Y2:=0 Else If Y2>Bh-1 Then Y2:=Bh-1;     //读取数据到 BMP 对象
         For I:=Y1 To Y2 Do
         Begin
              Seek(AFile,FileHead.bfOffBits+I*BytesPerLine+X1*3);
              BlockRead(AFile,ABMP.ScanLine[(H-1)-(I-Y1)]^,(X2-X1)*3);
         End;     CloseFile(AFile);
         {$I+}
    End;