这个问题也曾经困扰了我很长时间,直到在borland的新闻组上找到了答案。
下面是我的测试代码,写的很乱,凑活着看吧。
/////////////
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Math, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
TrackBar1: TTrackBar;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
gy=packed record
r:array [1..256] of word;
g:array [1..256] of word;//byte;
b:array [1..256] of word;//byte;
end;
type
TGammaRamp = packed record
R : array[0..255] of word;
G : array[0..255] of word;
B : array[0..255] of word;
end;
var
Form1: TForm1;
SYS_OldGamma : TGammaRamp;
implementation
{$R *.dfm}
// storeoldgamma
//
procedure StoreOldGamma;
var
DC : HDC;
begin
DC := GetDC(0);
GetDeviceGammaRamp(DC, SYS_OldGamma);
ReleaseDC(0, DC);
end;
// restoreoldgamma
//
procedure RestoreOldGamma;
var
DC : HDC;
begin
DC := GetDC(0);
SetDeviceGammaRamp(DC, SYS_OldGamma);
ReleaseDC(0, DC);
end;
// setgamma
// to 0 = brighter, to 255 = more normal gamma
function SetGamma(Value : byte) : TGammaRamp;
var
I ,x: integer;
DC : HDC;
V : integer;
begin
//SYS_OldGamma
{x:=0;
for i:=0 to 255 do
begin
if (i<>0) and (SYS_OldGamma.g<>0) and (SYS_OldGamma.g<>65535) then
begin
B := (i mod 256) / 256;
A := SYS_OldGamma.g / 65536;
C := (ln(A) / ln(B));
inc(x);
gs:=gs+c;
end;
end;
x:=0;
for i:=0 to 255 do
begin
if (i<>0) and (SYS_OldGamma.b<>0) and (SYS_OldGamma.b<>65535) then
begin
B := (i mod 256) / 256;
A := SYS_OldGamma.b / 65536;
C := (ln(A) / ln(B));
inc(x);
bs:=bs+c;
end;
end;
}
;
for I := 0 to 255 do begin//计算gamma值,很多文档中都没有这些说明
V := Round(255 * Power(I / 255, Abs(Value) / 255));
if V > 255 then
V := 255;
Result.R := V shl 8;
Result.G := V shl 8;
Result.B := V shl 8;
end;
DC := GetDC(0);
SetDeviceGammaRamp(DC, Result);
ReleaseDC(0, DC);
end;
function getGamma : word;
var
DC : HDC;
i,x:integer;
a,b,c,rs,bs,gs:double;
begin
StoreOldGamma;
x:=0;
rs:=0;
for i:=0 to 255 do
begin
if (i<>0) then //and (SYS_OldGamma.R<>0) and (SYS_OldGamma.R<>65535) then
begin
B := (i mod 256) / 256;
A := SYS_OldGamma.R / 65536;
C := (ln(A) / ln(B));
inc(x);
rs:=rs+c;
end;
end;
if x<>0 then
showmessage(inttostr(round(rs))+'::'+inttostr(round(x))+'::'+inttostr(round(rs/x)));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// StoreOldGamma;
SetGamma(58);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
// showmessage(inttostr(getGamma));
// RestoreOldGamma;
getGamma;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
SetGamma(TrackBar1.Position);
end;
end.