Вставить функцию
Добавлено: 28 сен 2005, 11:53
Вопрос, я в Дельфи новичок, нашел функцию изменения яркости изображения, но тут возник вопрос: а как ее применить?
Допустим я загружаю изображение слишком темное(в джпеге или бмп(в джпеге лучше)), хочу нажать на кнопку -чтобы изменить его яркость, соответвенно изображение перерисовывается на экране с измененной яркостью, далее нужно его сохранить.
Так вот суть вопроса:
Код процедуры взят из DRKB.
Так как это применить в программе? просто вызвать из обработки события в кнопке?(вопрос как правильно тогда), или нужно еще что-то делать с изображением?
Если кто может, подскажите или примерчик приведите...
допустим простенькая загрузка и выгрузка изображения есть: кое-как с примерами наваял...
Допустим я загружаю изображение слишком темное(в джпеге или бмп(в джпеге лучше)), хочу нажать на кнопку -чтобы изменить его яркость, соответвенно изображение перерисовывается на экране с измененной яркостью, далее нужно его сохранить.
Так вот суть вопроса:
Код: Выделить всё
Автор: Den Bedard
В данной статье хотелось бы показать принцип получения из обычного цвета более тёмный или более светлый. А так же рассмотрим, как этот принцип реализовани в программном коде.
Итак, немного теории:
Каждый из трёх основных цветов (Красный,Зелёный,Синий) могут иметь значение от 0 до 255, соответственно скомбинировав их мы можем получить 16,777,216 возможных цветов. Визуально это можно предствить как три оси куба, в котором направления x, y и z отвечают за цвета красный, зелёный и синий. В сочетании эти направления дают точку в кубе, представляющую один цвет из 16 миллионов. Точка куба, в которой значение равняется 0 (0,0,0) соответствует чёрному цвету, значение (255,255,255) - белому цвету, (255,0,0) - чисто красному, и т.д.
Если визуально провести линию между каким-либо цветом (r,g,b) и белым цветом (255,255,255), то получится, что на этой линии будут лежать все значения данного цвета (r,g,b). Если мы будем двигаться по линии в сторону белого цвета, то яркость будет увеличиваться до тех пор пока не получим чисто белый цвет.
То же самое можно сделать и для уменьшения яркости цвета. Достаточно провести линию из цвета (r,g,b) в чёрный (0,0,0). То есть при движении по линии к чёрному цвету мы будем уменьшать яркость до тех пор, пока не получим чёрный цвет.
Функция "Darker" возвращает новое значение цвета, которое будет на сколько-то процентов темнее. Естевственно, что при 100% мы получим чёрный цвет.
Функция "Lighter" возвращает цвет, который светлее на сколько-то процентов исходного. 100% - белый цвет.
Функции Darker и Lighter требуют 2 параметра и используются примерно так:
Panel1.Color := Darker(clBlue,20);
Получется панель цветов, которая на 20% темнее обычного синего цвета.
Теперь давайте посмотрим, как выглядят внутри наши функции:
function Darker(Color:TColor; Percent:Byte):TColor;
var
r,g,b:Byte;
begin
Color:=ColorToRGB(Color);
r:=GetRValue(Color);
g:=GetGValue(Color);
b:=GetBValue(Color);
r:=r-muldiv(r,Percent,100); //процент% уменьшения яркости
g:=g-muldiv(g,Percent,100);
b:=b-muldiv(b,Percent,100);
result:=RGB(r,g,b);
end;
function Lighter(Color:TColor; Percent:Byte):TColor;
var
r,g,b:Byte;
begin
Color:=ColorToRGB(Color);
r:=GetRValue(Color);
g:=GetGValue(Color);
b:=GetBValue(Color);
r:=r+muldiv(255-r,Percent,100); //процент% увеличения яркости
g:=g+muldiv(255-g,Percent,100);
b:=b+muldiv(255-b,Percent,100);
result:=RGB(r,g,b);
end;
Так же я добавил некоторые функции, в которых уже добавлены стандартные значения процентов. Это для тех, кому некогда задумываться над процентами :)
Panel1.Color := Light(clBlue);
Panel1.Color := SlightlyDark(clRed);
Panel1.Color := VeryLight(clMagenta);
etc.
function SlightlyDark(Color:TColor):TColor;
begin
Result := Darker(Color,25);
end;
function Dark(Color:TColor):TColor;
begin
Result := Darker(Color,50);
end;
function VeryDark(Color:TColor):TColor;
begin
Result := Darker(Color,75);
end;
function SlightlyLight(Color:TColor):TColor;
begin
Result := Lighter(Color,25);
end;
function Light(Color:TColor):TColor;
begin
Result := Lighter(Color,50);
end;
function VeryLight(Color:TColor):TColor;
begin
Result := Lighter(Color,75);
end;
Так как это применить в программе? просто вызвать из обработки события в кнопке?(вопрос как правильно тогда), или нужно еще что-то делать с изображением?
Если кто может, подскажите или примерчик приведите...
допустим простенькая загрузка и выгрузка изображения есть: кое-как с примерами наваял...
Код: Выделить всё
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtDlgs, StdCtrls, ExtCtrls, JPEG,Spin,Map, Menus;
type
TForm1 = class(TForm)
SBox: TScrollBox;
PBox: TPaintBox;
Opd: TOpenPictureDialog;
Spd: TSavePictureDialog;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
procedure PBoxPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure spZoomChange(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure N4Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N3Click(Sender: TObject);
{ procedure N5Click(Sender: TObject);}
private
{ Private declarations }
procedure InitAllMap;
procedure FreeAllMap;
procedure LoadImage(FileName:string);
public
{ Public declarations }
end;
var
Form1: TForm1;
Pic:TBitmap;
PicRect:TRect;
ZoomRect:TRect;
kz:integer; // koefficient zooming
w,h:integer; // Øèðèíà è Âûñîíà
FileName:string;
m0:TMap;
m1,m2,m3:TMap;
implementation
uses Filtres;
{$R *.DFM}
procedure TForm1.InitAllMap;
// èíèöèàëèçàöèÿ ðàáî÷èõ ìàññèâîâ
begin
InitMap(m0,w,h);
InitMap(m1,w,h);
InitMap(m2,w,h);
InitMap(m3,w,h);
end;
procedure TForm1.FreeAllMap;
// îñâîáîæäåíèå ðàáî÷èõ ìàññèâîâ
begin
FreeMap(m0);
FreeMap(m1);
FreeMap(m2);
FreeMap(m3);
end;
procedure TForm1.LoadImage(FileName:string);
// çàãðóçêà èçîáðàæåíèÿ
var bmp:TBitmap;
ww,hh,pw,ph:integer;
jpg:TJpegImage;
ext:string;
begin
if FileName='' then Exit;
bmp:=TBitmap.Create;
try
ext:=ExtractFileExt(FileName);
if (ext='.jpg') or (ext='.jpeg') then
begin
jpg:=TJpegImage.Create;
try
jpg.LoadFromFile(FileName);
bmp.Assign (jpg);
finally
jpg.Free; end
end
else
bmp.LoadFromFile(FileName);
w:=bmp.Width;
h:=bmp.Height;
kz:=1;
PicRect:=Rect(0,0,w,h);
ZoomRect:=Rect(0,0,w*kz,h*kz);
if pic<>nil then begin pic.Free; pic:=nil; end;
pic:=TBitmap.Create;
pic.Width:=w;
pic.Height:=h;
pic.PixelFormat:=pf24bit;
//êîíâåðòàöèÿ â TrueColor
pic.Canvas.CopyRect(PicRect,bmp.Canvas,PicRect);
InitAllMap;
GetLightness(pic,m0);
finally bmp.Free;
end;
end;
procedure TForm1.PBoxPaint(Sender: TObject);
//îòðèñîâêà
begin
PBox.Canvas.StretchDraw(ZoomRect,pic);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
kz:=1;
FileName:='';
end;
{äëÿ ïðîêðóòêè}
procedure TForm1.spZoomChange(Sender: TObject);
var x,y,x0,y0,kz0:integer;
begin
kz0:=kz;
x0:=SBox.HorzScrollBar.Position;
y0:=SBox.VertScrollBar.Position;
x:=Round(x0*(kz/kz0));
y:=Round(y0*(kz/kz0));
ZoomRect:=Rect(0,0,w*kz,h*kz);
SBox.AutoScroll:=false;
PBox.height:=h*kz;
PBox.width:=w*kz;
SBox.AutoScroll:=true;
SBox.HorzScrollBar.Position:=x;
SBox.VertScrollBar.Position:=y;
end;
//ïðè âûõîäå î÷èùàåì
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAllMap;
pic.Free;
end;
procedure TForm1.N4Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.N2Click(Sender: TObject);
begin
try
if Opd.Execute then
begin
FileName:=Opd.FileName;
LoadImage(FileName);
Pbox.refresh;
PboxPaint(nil);
spZoomChange(nil);
Form1.Caption:=ExtractFileName(FileName)+
' ['+IntToStr(w) + ' * ' + IntToStr(h)+']';
Opd.InitialDir:=Opd.GetNamePath;
end;
except
Application.MessageBox(
'Error Load from File','Error',MB_OK);
end;
end;
{ñîõðàíåíèå èçìåíåíèé}
procedure TForm1.N3Click(Sender: TObject);
var jpg:TJpegImage;
sn,f:string;
n:integer;
label inp;
begin
if Spd.Execute then
begin
f:=spd.FileName;
Case Spd.FilterIndex of
// Ñîõðàíåíè â ÁÌÐ
1: begin
spd.DefaultExt:='bmp';
f:=ChangeFileExt(f,'.bmp');
pic.SaveToFile(f);
end;
// èëè ñîõðàíåíèå â JPEG
2: begin
jpg:=TJpegImage.Create;
spd.DefaultExt:='jpg';
f:=ChangeFileExt(f,'.jpg');
try
n:=100;
jpg.CompressionQuality:=n;
jpg.Assign(pic);
jpg.SaveToFile(f);
finally jpg.Free; end;
end;
end;
end;
end;
end.
Тут конечно много закоментировано, так как переделывал немного, но в принципе работает... а вот со вставкой функции затруднения...