最近在做视频处理相关的工作,遇到一些图片处理的问题,从别处找到解决的代码。
其中对比度调节的代码处理结果看起来不太舒服,暂时没时间仔细研究,先放在这里。
// 改亮度
function ChangeBrightness(bmp: TBitmap; s: Integer): Boolean;
var
p: PByteArray;
x, y: Integer;
begin
try
//24位真彩色
Bmp.PixelFormat := pf24Bit;
bmp.Canvas.Lock;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin
//每个象素点的R、G、B分量进行调节
begin
if s > 0 then
begin
p[x * 3] := Min(255, p[x * 3] + s); //不能越界,限制在0~255
p[x * 3 + 1] := Min(255, p[x * 3 + 1] + s);
p[x * 3 + 2] := Min(255, p[x * 3 + 2] + s);
end
else
begin
p[x * 3] := max(0, p[x * 3] + s); //不能越界,限制在-255~0
p[x * 3 + 1] := max(0, p[x * 3 + 1] + s);
p[x * 3 + 2] := max(0, p[x * 3 + 2] + s);
end;
end;
end;
end;
bmp.Canvas.Unlock;
Result := true;
except
Result := false;
end;
end;
// 改对比度
function ChangeContrast(bmp: TBitmap; s: Integer): Boolean;
const
CMid = 128;
CMin = 10;
CMax = 246;
var
p: PByteArray;
x, y: Integer;
begin
try
//24位真彩色
Bmp.PixelFormat := pf24Bit;
bmp.Canvas.Lock;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.ScanLine[y];
for x := 0 to Bmp.Width - 1 do
begin
//确定阀值为128
if (p[x*3] > CMid) and (p[x*3] <= CMax)
and (p[x*3+1] > CMid) and (p[x*3+1] <= CMax)
and (p[x*3+2] > CMid) and (p[x*3+2] <= CMax) then
begin
p[x*3] := Min(255, p[x*3] + s * p[x*3] div (p[x*3]+p[x*3+1]+p[x*3+2]));
p[x*3+1]:= Min(255, p[x*3+1]+ s * p[x*3+1] div (p[x*3]+p[x*3+1]+p[x*3+2]));
p[x*3+2]:= Min(255, p[x*3+2]+ s * p[x*3+2] div (p[x*3]+p[x*3+1]+p[x*3+2]));
end;
if (p[x*3] > CMin) and (p[x*3] <= CMid)
and (p[x*3+1] > CMin) and (p[x*3+1] <= CMid)
and (p[x*3+2] > CMin) and (p[x*3+2] <= CMid) then
begin
p[x*3] := Max(0, p[x*3] - s * p[x*3] div (p[x*3]+p[x*3+1]+p[x*3+2]));
p[x*3+1]:= Max(0, p[x*3+1]- s * p[x*3+1] div (p[x*3]+p[x*3+1]+p[x*3+2]));
p[x*3+2]:= Max(0, p[x*3+2]- s * p[x*3+2] div (p[x*3]+p[x*3+1]+p[x*3+2]));
end;
end;
end;
bmp.Canvas.Unlock;
Result := true;
except
Result := false;
end;
end;
// 改饱和度
function ChangeSaturation(bmp: TBitmap; ValueChange: Integer): Boolean;
const
CMax = 255;
var
Grays: array[0..767] of Integer;
Alpha: array[0..255] of Word;
Gray, x, y: Integer;
SrcRGB: PRGBTriple;
i: Byte;
begin
ValueChange := ValueChange + 255;
for i := 0 to CMax do
begin
Alpha[i] := (i * ValueChange) shr 8;
end;
x := 0;
for i := 0 to CMax 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 bmp.Height - 1 do
begin
SrcRGB := bmp.ScanLine[y];
for x := 0 to bmp.Width - 1 do
begin
Gray := Grays[SrcRGB.rgbtRed + SrcRGB.rgbtBlue + SrcRGB.rgbtGreen];
if Gray + Alpha[SrcRGB.rgbtRed] > 0 then
SrcRGB.rgbtRed := Min(CMax, Gray + Alpha[SrcRGB.rgbtRed])
else
SrcRGB.rgbtRed := 0;
if Gray + Alpha[SrcRGB.rgbtGreen] > 0 then
SrcRGB.rgbtGreen := Min(CMax, Gray + Alpha[SrcRGB.rgbtGreen])
else
SrcRGB.rgbtGreen := 0;
if Gray + Alpha[SrcRGB.rgbtBlue] > 0 then
SrcRGB.rgbtBlue := Min(CMax, Gray + Alpha[SrcRGB.rgbtBlue])
else
SrcRGB.rgbtBlue := 0;
Inc(SrcRGB);
end;
end;
end;