// 说明:用于处理的BITMAP必须是24bit的,如果不是则需要先转为24BIT
// 这是从我正在开发的眼科影像处理系统中直接取出来的,尚未进行优化,
// 但是肯定能正常工作,且效率高(你可以将这段代码放在一个滚动条
// 的 OnChange 事件中,你可以看到随着滚动条的移动图象的变化)
procedure bmpbright(mybitmap: tbitmap; // 用来处理的BITMAP,要求24BIT
brightness: integer; // 亮度,范围:0-255
contrast: integer; // 对比度,范围:0-255
displayingray: boolean; // 是否显示为灰度,TRUE为灰度
reversedisplay: boolean; // 是否显示负片效果,TRUE为负片
colorfilter: byte; // 颜色过滤:1=滤赤色,2=荧光色
x1,y1,x2,y2: integer); // 处理区域
var
thew,theh: integer;
i,j: integer;
p: pbytearray;
colorlevel: int64;
sty,stx,eny,enx: integer;
bripos,conpos: integer;
sum1,sum2,sum3: int64;
ave1,ave2,ave3: integer;
times: integer;
rlevel,glevel,blevel: integer;
maxnum,minnum: integer;
begin
conpos:=contrast+100;
times:=conpos;
if conpos>100 then times:=conpos*conpos div 100;
with mybitmap do
begin
thew:=width;
theh:=height;
if (x1=x2) or (y1=y2) then
begin
x1:=1;
y1:=1;
x2:=thew-1;
y2:=theh-1;
end
else
begin
minnum:=min(y1,y2);
maxnum:=max(y1,y2);
y1:=minnum;
y2:=maxnum;
minnum:=min(x1,x2);
maxnum:=max(x1,x2);
x1:=minnum;
x2:=maxnum;
end;
if x1<1 then x1:=1;
if y1<1 then y1:=1;
if x2>thew-1 then x2:=thew-1;
if y2>theh-1 then y2:=theh-1;
sum1:=0;
sum2:=0;
sum3:=0;
for i:=y1 to y2 do
begin
p:=scanline;
for j:=x1 to x2 do
begin
sum1:=sum1+p[j*3+2];
sum2:=sum2+p[j*3+1];
sum3:=sum3+p[j*3];
end;
end;
ave1:=sum1 div ((y2-y1+1)*(x2-x1+1));
ave2:=sum2 div ((y2-y1+1)*(x2-x1+1));
ave3:=sum3 div ((y2-y1+1)*(x2-x1+1));
for i:=y1 to y2 do
begin
p:=scanline;
for j:=x1 to x2 do
begin
colorlevel:=((p[j*3+2]-ave1)*times div 100)+ave1+brightness;
if colorlevel>255 then colorlevel:=255;
if colorlevel<0 then colorlevel:=0;
p[j*3+2]:=colorlevel;
colorlevel:=((p[j*3+1]-ave2)*times div 100)+ave2+brightness;
if colorlevel>255 then colorlevel:=255;
if colorlevel<0 then colorlevel:=0;
p[j*3+1]:=colorlevel;
colorlevel:=((p[j*3]-ave3)*times div 100)+ave3+brightness;
if colorlevel>255 then colorlevel:=255;
if colorlevel<0 then colorlevel:=0;
p[j*3]:=colorlevel;
if colorfilter=1 then
p[j*3+2]:=0;
if colorfilter=2 then
begin
p[j*3+2]:=0;
p[j*3]:=0;
end;
if displayingray then
begin
rlevel:=p[j*3+2];
glevel:=p[j*3+1];
blevel:=p[j*3];
colorlevel:=rlevel*rlevel+glevel*glevel+blevel*blevel;
colorlevel:=colorlevel div (rlevel+glevel+blevel+1);
p[j*3]:=colorlevel;
p[j*3+1]:=colorlevel;
p[j*3+2]:=colorlevel;
end;
if reversedisplay then
begin
p[j*3]:=$ff-p[j*3];
p[j*3+1]:=$ff-p[j*3+1];
p[j*3+2]:=$ff-p[j*3+2];
end;
end;
end;
end;
end;