真是见鬼了,我发了三次了,算了,我把代码贴出来吧!
{-----------------------------------------------------------------------------
Unit Name: Unit1
Author: huazai
Purpose: HSL and RGB transform
History:
-----------------------------------------------------------------------------}
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtDlgs, StdCtrls, ExtCtrls, ComCtrls;
const
MaxPixelCount = 65536;
type
TReal = Single;
// use SysUtils.pByteArray for pf8bit Scanlines
// For pf24bit Scanlines
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..MaxPixelCount - 1] of TRGBTriple;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
Button2: TButton;
OpenPictureDialog1: TOpenPictureDialog;
Image2: TImage;
Button3: TButton;
Hadjust: TButton;
TrackBar1: TTrackBar;
Label1: TLabel;
TrackBar2: TTrackBar;
Label2: TLabel;
TrackBar3: TTrackBar;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure HadjustClick(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
procedure TrackBar3Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Math, hsv;
{$R *.dfm}
procedure HSLtoRGB(H, S, L: Integer; var R, G, B: Integer);
//hsl颜色空间到rgb空间的转换
var //类似于返回多个值的函数
Sat, Lum: Double;
begin
R := 0;
G := 0;
B := 0;
if (H < 360) and (H >= 0) and (S <= 100) and (S >= 0) and (L <= 100) and (L
>=
0) then
begin
if H <= 60 then
begin
R := 255;
G := Round((255 / 60) * H);
B := 0;
end
else if H <= 120 then
begin
R := Round(255 - (255 / 60) * (H - 60));
G := 255;
B := 0;
end
else if H <= 180 then
begin
R := 0;
G := 255;
B := Round((255 / 60) * (H - 120));
end
else if H <= 240 then
begin
R := 0;
G := Round(255 - (255 / 60) * (H - 180));
B := 255;
end
else if H <= 300 then
begin
R := Round((255 / 60) * (H - 240));
G := 0;
B := 255;
end
else if H < 360 then
begin
R := 255;
G := 0;
B := Round(255 - (255 / 60) * (H - 300));
end;
Sat := Abs((S - 100) / 100);
R := Round(R - ((R - 128) * Sat));
G := Round(G - ((G - 128) * Sat));
B := Round(B - ((B - 128) * Sat));
Lum := (L - 50) / 50;
if Lum > 0 then
begin
R := Round(R + ((255 - R) * Lum));
G := Round(G + ((255 - G) * Lum));
B := Round(B + ((255 - B) * Lum));
end
else if Lum < 0 then
begin
R := Round(R + (R * Lum));
G := Round(G + (G * Lum));
B := Round(B + (B * Lum));
end;
end;
end;
procedure RGBtoHSL(R, G, B: Integer; var H, S, L: Integer);
// RGB空间到HSL空间的转换
var
Delta: Double;
CMax, CMin: Double;
Red, Green, Blue, Hue, Sat, Lum: Double;
begin
Red := R / 255;
Green := G / 255;
Blue := B / 255;
CMax := Max(Red, Max(Green, Blue));
CMin := Min(Red, Min(Green, Blue));
Lum := (CMax + CMin) / 2;
if CMax = CMin then
begin
Sat := 0;
Hue := 0;
end
else
begin
if Lum < 0.5 then
Sat := (CMax - CMin) / (CMax + CMin)
else
Sat := (cmax - cmin) / (2 - cmax - cmin);
delta := CMax - CMin;
if Red = CMax then
Hue := (Green - Blue) / Delta
else if Green = CMax then
Hue := 2 + (Blue - Red) / Delta
else
Hue := 4.0 + (Red - Green) / Delta;
Hue := Hue / 6;
if Hue < 0 then
Hue := Hue + 1;
end;
H := Round(Hue * 360);
S := Round(Sat * 100);
L := Round(Lum * 100);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Self.OpenPictureDialog1.Filter := '*.bmp|*.bmp';
if OpenPictureDialog1.Execute then
begin
Image1.Picture.Bitmap.LoadFromFile(OpenPictureDialog1.FileName);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(image1.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin
//获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
//饱和度值进行线性调节。
lVALUE := lVALUE + 20;
lVALUE := min(100, lVALUE);
//下面两行是饱和度度减小操作
//SVALUE := SVALUE - 5;
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
image2.Picture.Bitmap.Assign(bmp);
Bmp.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(image1.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin
//获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
//饱和度值进行线性调节。
sVALUE := sVALUE + 20;
sVALUE := min(100, sVALUE);
//下面两行是饱和度度减小操作
//SVALUE := SVALUE - 5;
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
image2.Picture.Bitmap.Assign(bmp);
Bmp.Free;
end;
procedure TForm1.HadjustClick(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(image1.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin
//获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
//饱色度值进行线性调节。
hVALUE := hVALUE + 20;
sVALUE := min(180, hVALUE);
//下面两行是饱和度度减小操作
//SVALUE := SVALUE - 5;
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
image2.Picture.Bitmap.Assign(bmp);
Bmp.Free;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(image1.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin
//获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
//饱色度值进行线性调节。
hVALUE := hVALUE + TrackBar1.Position;
hVALUE := max(0, min(359, hVALUE));
//下面两行是饱和度度减小操作
//SVALUE := SVALUE - 5;
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
image2.Picture.Bitmap.Assign(bmp);
image2.Repaint;
Bmp.Free;
end;
procedure TForm1.TrackBar2Change(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(image1.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin
//获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
//饱和度值进行线性调节。
lVALUE := lVALUE + TrackBar2.Position;
lVALUE := Max(0, min(99, lVALUE));
//下面两行是饱和度度减小操作
//SVALUE := SVALUE - 5;
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
image2.Picture.Bitmap.Assign(bmp);
image2.Repaint;
Bmp.Free;
end;
procedure TForm1.TrackBar3Change(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(image1.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin
//获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
//饱和度值进行线性调节。
sVALUE := sVALUE + TrackBar3.Position;
sVALUE := max(0, min(99, sVALUE));
//下面两行是饱和度度减小操作
//SVALUE := SVALUE - 5;
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
image2.Picture.Bitmap.Assign(bmp);
image2.Repaint;
Bmp.Free;
end;
end.