Как изменить яркость и контраст?

You must change the RBG values of the pixels. For 1, 4 and 8 bit bitmaps, you must edit the palette. For 15 - 32 bit bitmaps, you must edit the pixel direct. For larger bitmaps you should precalulate a table and set the RGB values from this table.
Red := BCTable[Red];
Green := BCTable[Green];
Blue := BCTable[Blue];
You can find the calculation of the table below. The rest is standard source code, look at EFG's Computer Lab for any solution.
I define the brightness and contrast value between 0..255. Other definitions are possible, change BMax, CMax, BNorm and CNorm.

type

 TBCTable = array[Byte] of Byte;

const

 RGBCount = 256;

 RGBMax = 255;

 RGBHalf = 128;

 RGBMin = 0;

 BMax = 128; { Maximal value brightness 100% - 0% = 0% - - 100% }

 CMax = 128; { Maximal value contrast 100% - 0% = 0% - - 100% }

 BNorm = 128; { Normal value brightness 0% }

 CNorm = 128; { Normal value contrast 0% }

procedure CalcBCTable(var ABCTable: TBCTable; ABrightness, AContrast: Integer);

var

 i, v: Integer;

 BOffset: Integer;

 M, D: Integer;

begin

 Dec(ABrightness, BNorm);

 Dec(AContrast, CNorm);

 { precalculation brightness assistance values }

 BOffset := ((ABrightness) * RGBMax div BMax);

 { precalculation contrast assistance values }

 if AContrast < CMax then

 begin { because Division by 0 on 100% }

  if AContrast <= 0 then

  begin { decrement contrast }

  M := CMax + AContrast;

  D := CMax;

  end

  else

  begin { increment contrast }

  M := CMax;

  D := CMax - AContrast;

  end;

 end

 else

 begin

  M := 0;

  D := 1;

 end;

 for i := RGBMin to RGBMax do

 begin

  { calculate contrast }

  if AContrast < CMax then

  begin

  v := ((i - RGBHalf) * M) div D + RGBHalf;

  { restrict to byte range }

  if v < RGBMin then

  v := RGBMin

  else if v > RGBMax then

  v := RGBMax;

  end

  else

  begin { contrast = 100% }

  if i < RGBHalf then

  v := RGBMin

  else

  v := RGBMax;

  end;

  { calculate brightness }

  Inc(v, BOffset);

  { restrict to byte range }

  if v < RGBMin then

  v := RGBMin

  else if v > RGBMax then

  v := RGBMax;

  ABCTable[i] := v;

 end;

end;

Add a fixed value and clip it to the range. I have used a LUT, which is faster for larger bitmaps. The range of Brightness is -255 (-100%) to 255 (+100%). You can use a 32 or 24 Bit calculation depending on the compiler setting ChangeBrightness24Bit.

procedure ChangeBrightness(Bitmap: TBitmap; Brightness: Integer);

var

 LUT: array[Byte] of Byte;

 v, i: Integer;

{$IFDEF ChangeBrightness24Bit}

 w, h, x, y: Integer;

 LineSize: LongInt;

 pLineStart: PByte;

{$ENDIF}

 p: PByte;

begin

 { create LUT }

 for i := 0 to 255 do

 begin

  v := i + Brightness;

  if v < 0 then

  v := 0

  else if v > 255 then

  v := 255;

  LUT[i] := v;

 end;

{$IFDEF ChangeBrightness24Bit}

 { edit bitmap }

 w := Bitmap.Width;

 h := Bitmap.Height - 1;

 Bitmap.PixelFormat := pf24Bit;

 pLineStart := PByte(Bitmap.ScanLine[h]);

 { pixel line is aligned to 32 Bit }

 LineSize := ((w * 3 + 3) div 4) * 4;

 w := w * 3 - 1;

 for y := 0 to h do

 begin

  p := pLineStart;

  for x := 0 to w do

  begin

  p^ := LUT[p^];

  Inc(p);

  end;

  Inc(pLineStart, LineSize);

 end;

{$ELSE}

 { edit bitmap }

 Bitmap.PixelFormat := pf32Bit;

 p := PByte(Bitmap.ScanLine[Bitmap.Height - 1]);

 for i := 0 to Bitmap.Width * Bitmap.Height - 1 do

 begin

  p^ := LUT[p^];

  Inc(p);

  p^ := LUT[p^];

  Inc(p);

  p^ := LUT[p^];

  Inc(p, 2);

 end;

{$ENDIF}

end;

Взято с Delphi Knowledge Base: http://www.baltsoft.com/

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...