有谁知道Image图像组件调节亮度、对比度、饱和度的算法?

解决方案 »

  1.   

    //亮度调整
    procedure BrightnessChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer);
    var
      i, j: integer;
      SrcRGB, DestRGB: pRGBTriple;
      Table: array[0..255]of Byte;
    begin
      if ValueChange > 0 then
        for i := 0 to 255 do
          Table[i]:=Byte(i + ((ValueChange * (i xor 255)) shr 8))
      else
        for i := 0 to 255 do
          Table[i]:=Byte(i - ((Abs(ValueChange) * i) shr 8));
      for i := 0 to SrcBmp.Height - 1 do
      begin
        SrcRGB := SrcBmp.ScanLine[i];
        DestRGB := DestBmp.ScanLine[i];
        for j := 0 to SrcBmp.Width - 1 do
        begin
          DestRGB^.rgbtRed := Table[SrcRGB^.rgbtRed];
          DestRGB^.rgbtGreen := Table[SrcRGB^.rgbtGreen];
          DestRGB^.rgbtBlue := Table[SrcRGB^.rgbtBlue];
          Inc(SrcRGB);
          Inc(DestRGB);
        end;
      end;
    end;//对比度调整
    procedure ContrastChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer);
    var
      i, j: integer;
      SrcRow, DestRow: pRGBTriple;
    begin
      for i := 0 to SrcBmp.Height - 1 do
      begin
        SrcRow := SrcBmp.ScanLine[i];
        DestRow := DestBmp.ScanLine[i];
        for j := 0 to SrcBmp.Width - 1 do
        begin
          if ValueChange>=0 then
          begin
          if SrcRow.rgbtRed >= 128 then
            DestRow.rgbtRed := Min(255, SrcRow.rgbtRed + (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128)
          else
            DestRow.rgbtRed := Max(0, SrcRow.rgbtRed - (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128);
          if SrcRow.rgbtGreen >= 128 then
            DestRow.rgbtGreen := Min(255, SrcRow.rgbtGreen + (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128)
          else
            DestRow.rgbtGreen := Max(0, SrcRow.rgbtGreen - (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128);
          if SrcRow.rgbtBlue >= 128 then
            DestRow.rgbtBlue := Min(255, SrcRow.rgbtBlue + (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128)
          else
            DestRow.rgbtBlue := Max(0, SrcRow.rgbtBlue - (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128);
          end
          else
          begin
          if SrcRow.rgbtRed >= 128 then
            DestRow.rgbtRed := Max(128, SrcRow.rgbtRed + (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128)
          else
            DestRow.rgbtRed := Min(128, SrcRow.rgbtRed - (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128);
          if SrcRow.rgbtGreen >= 128 then
            DestRow.rgbtGreen := Max(128, SrcRow.rgbtGreen + (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128)
          else
            DestRow.rgbtGreen := Min(128, SrcRow.rgbtGreen - (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128);
          if SrcRow.rgbtBlue >= 128 then
            DestRow.rgbtBlue := Max(128, SrcRow.rgbtBlue + (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128)
          else
            DestRow.rgbtBlue := Min(128, SrcRow.rgbtBlue - (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128);
          end;
          Inc(SrcRow);
          Inc(DestRow);
        end;
      end;
    end;//饱和度调整
    procedure SaturationChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer);
    var 
      Grays: array[0..767] of Integer;
      Alpha: array[0..255] of Word;
      Gray, x, y: Integer;
      SrcRGB,DestRGB: pRGBTriple;
      i: Byte;
    begin
    ValueChange:=ValueChange+255;
    for i := 0 to 255 do
      Alpha[i] := (i * ValueChange) Shr 8;
    x := 0;
    for i := 0 to 255 do
    begin 
      Gray := i - Alpha[i];
      Grays[x] := Gray;
      Inc(x);
      Grays[x] := Gray;
      Inc(x);
      Grays[x] := Gray;
      Inc(x);
    end; 
    for y := 0 to SrcBmp.Height - 1 do
    begin
      SrcRGB := SrcBmp.ScanLine[Y];
      DestRGB := DestBmp.ScanLine[Y];
      for x := 0 to SrcBmp.Width - 1 do
      begin
        Gray := Grays[SrcRGB.rgbtRed + SrcRGB.rgbtGreen + SrcRGB.rgbtBlue];
        if Gray + Alpha[SrcRGB.rgbtRed]>0 then
          DestRGB.rgbtRed := Min(255,Gray + Alpha[SrcRGB.rgbtRed])
        else
          DestRGB.rgbtRed := 0;
        if Gray + Alpha[SrcRGB.rgbtGreen]>0 then
          DestRGB.rgbtGreen := Min(255,Gray + Alpha[SrcRGB.rgbtGreen])
        else
          DestRGB.rgbtGreen := 0;
        if Gray + Alpha[SrcRGB.rgbtBlue]>0 then
          DestRGB.rgbtBlue := Min(255,Gray + Alpha[SrcRGB.rgbtBlue])
        else
          DestRGB.rgbtBlue := 0;
        Inc(SrcRGB);
        Inc(DestRGB);
      end;
    end; 
    end;