代码之家  ›  专栏  ›  技术社区  ›  Mahmoud

Delphi中的图像校验和

  •  0
  • Mahmoud  · 技术社区  · 16 年前

    我尝试对一个图像进行校验和,但是给出结果的时间太长,尝试了添加值,Adler-32但是都在很长的时间(大约2秒)内完成。

    添加值:

    Function Checksum_CountryFlag(Img : TPicture):Integer;
    var j, k, Checksum : Integer;
    begin
    Checksum := 0;
    For j := 0 to Img.Width do
    For k := 0 to Img.Height do
    If (((Img.Bitmap.Canvas.Pixels[j,k]) <> 15577344) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 15311104) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 3816255) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 10526623) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 12303034) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 9013641)) Then
    begin
    Checksum := Checksum + Img.Bitmap.Canvas.Pixels[j,k];
    end;
    Result := Abs(Checksum);
    end;
    

    阿德勒-32:

    Function Checksum_Adler32(Img : TPicture):Integer;
    var i,a,b,j,k : Integer;
    begin
    a := 1; b := 0;
    For j := 0 to Img.Width do
    For k := 0 to Img.Height do
    If (((Img.Bitmap.Canvas.Pixels[j,k]) <> 15577344) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 15311104) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 3816255) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 10526623) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 12303034) And ((Img.Bitmap.Canvas.Pixels[j,k]) <> 9013641)) Then
    begin
    a := a + Img.Bitmap.Canvas.Pixels[j,k];
    b := b + a;
    end;
    Result := Abs(a) + Abs(b);
    end;
    

    如您所见,我试图避免使用某些值(技术原因)。

    4 回复  |  直到 16 年前
        1
  •  6
  •   kludg    16 年前

    我已经做了一些修正,使您的代码的第一个版本更快:

    Function Checksum_CountryFlag(Img : TPicture):Integer;
    var j, k, Checksum : Integer;
      Line: PLongInt;
    begin
      Checksum := 0;
      Img.Bitmap.PixelFormat:= pf32bit; // just for case
      For k := 0 to Img.Height - 1 do begin      //  !! Height first, -1
        Line:= Img.Bitmap.ScanLine[k];
        For j := 0 to Img.Width - 1 do begin  // !! -1
          If ((Line^ <> 15577344) And (Line^ <> 15311104) And (Line^ <> 3816255)
            And (Line^ <> 10526623) And (Line^ <> 12303034) And (Line^ <> 9013641)) Then
            begin
              Checksum := Checksum + Line^;
            end;
          Inc(Line);
        end;
      end;
      Result := Abs(Checksum);
    end;
    

    更新时间:

        2
  •  2
  •   BennyBechDk    16 年前

    解开循环中的部分可以提供更高的性能(lig将img.bitmap.canvas放入循环外的变量中)。

    但最大的影响可能是使用“Scanline”属性,并将一行中的所有像素都转换为一个局部变量,这会有更大的帮助(必须切换循环的高度和宽度)。

        3
  •  2
  •   Mason Wheeler    16 年前

    没有剖析器很难确定,但看看这个,我猜你会浪费很多时间来查找 Img.Bitmap.Canvas.Pixels[j,k]

    我要做的第一件事就是把它保存为一个值,比如:

    pixel := Img.Bitmap.Canvas.Pixels[j,k];
    If ((pixel <> 15577344) And (pixel <> 15311104) And (pixel <> 3816255) And (pixel <> 10526623) And (pixel <> 12303034) And (pixel <> 9013641)) Then
    

    这将大大加快事情的发展。

        4
  •  2
  •   BennyBechDk    16 年前

    具有校正(更快)像素值的Serg代码:

    Function Checksum_CountryFlag(Img : TPicture):Integer;
    var j, k, Checksum : Integer;
      Line: PIntegerArray;
      Pixel : integer;
    begin
      Checksum := 0;
      Img.Bitmap.PixelFormat:= pf32bit; // just for case
      For k := 0 to Img.Height - 1 do begin      //  !! Height first, -1
        Line:= Img.Bitmap.ScanLine[k];
        For j := 0 to Img.Width - 1 do begin  // !! -1
          Pixel := Line^[j];
          If ((Pixel <> 15577344) And (Pixel <> 15311104) And (Pixel <> 3816255)
            And (Pixel <> 10526623) And (Pixel <> 12303034) And (Pixel <> 9013641)) Then
            begin
              Checksum := Checksum + Pixel;
            end;
          Inc(Line);
        end;
      end;
      Result := Abs(Checksum);
    end;