Как изменить яркость и контраст?
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: https://www.baltsoft.com/