2009. január 18., vasárnap

How to change brightness and contrast in large bitmaps


Problem/Question/Abstract:

How to change brightness and contrast in large bitmaps

Answer:

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;

Nincsenek megjegyzések:

Megjegyzés küldése