Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВКР Красковой Н.И.doc
Скачиваний:
18
Добавлен:
05.11.2018
Размер:
1.07 Mб
Скачать

Меню «Файл» Элемент Меню «Файл» - подменю «Параметры страницы»

procedure TForm3.N10Click(Sender: TObject);

begin

PageSetupDialog1.Execute;

end;

Вызывает диалоговое окно «Параметры страницы» через компонент PageSetupDialog.

Элемент Меню «Файл» - подменю «Вывод на печать»

procedure TForm3.N9Click(Sender: TObject);

var

relheight, relwidth: integer;

koef: real;

begin

if printDialog1.Execute then

begin

//Печать изображения

with Printer do

begin

BeginDoc;

koef:=image1.Picture.Height/image1.Picture.Width;

Canvas.StretchDraw(Rect(0,0,PageWidth,Round(PageWidth*koef)), Image1.Picture.Graphic);

Вызывает диалоговое окно «Печать» через компонент PrintDialog.

Элемент Меню «Файл» - подменю «Закрыть»

procedure TForm3.N4Click(Sender: TObject);

begin

close;

end;

Процедура закрывает форму «Преобразования изображений».

2.2.3. Реализация алгоритмов интерполяции

Фрагмент кода алгоритма билинейной интерполяции:

function interpolate(bm: tbitmap; dx, dy: single):TBitmap;

var

bm1: tbitmap;

z1, z2: single;

k, k1, k2: single;

x1, y1: integer;

c: array [0..1, 0..1, 0..2] of byte;

res: array [0..2] of byte;

x, y: integer;

xp, yp: integer;

xo, yo: integer;

col: integer;

pix: tcolor;

begin

bm1 := tbitmap.create;

bm1.width := round(bm.width * dx);

bm1.height := round(bm.height * dy);

for y := 0 to bm1.height - 1 do begin

for x := 0 to bm1.width - 1 do begin

xo := trunc(x / dx);

yo := trunc(y / dy);

x1 := round(xo * dx);

y1 := round(yo * dy);

for yp := 0 to 1 do

for xp := 0 to 1 do begin

pix := bm.canvas.pixels[xo + xp, yo + yp];

c[xp, yp, 0] := getrvalue(pix);

c[xp, yp, 1] := getgvalue(pix);

c[xp, yp, 2] := getbvalue(pix);

end;

for col := 0 to 2 do begin

k1 := (c[1,0,col] - c[0,0,col]) / dx;

z1 := x * k1 + c[0,0,col] - x1 * k1;

k2 := (c[1,1,col] - c[0,1,col]) / dx;

z2 := x * k2 + c[0,1,col] - x1 * k2;

k := (z2 - z1) / dy;

res[col] := round(y * k + z1 - y1 * k);

end;

bm1.canvas.pixels[x,y] := rgb(res[0], res[1], res[2]);

end;

Form3.Caption := IntToStr(round(100 * y / bm1.Height)) + '%';

Application.ProcessMessages;

if Application.Terminated then

Exit;

end;

bm := bm1;

interpolate:=bm1;

end;

Изображение рассматривается как поверхность, цвет - третье измерение. Если изображение цветное, то интерполяция проводится отдельно для трех цветов. 

Для каждой точки нового изображения с координатами (xo,yo) нужно найти четыре ближайшие точки исходного изображения.  Эти точки образуют квадрат. Через две верхние точки проводится прямая f1(x), через две нижние - f2(x). Дальше находятся координаты для точек f1(xo) и f2(xo), через которые проводится третья прямая f3(y). Цвет искомой точки - это f3(yo). 

Этот алгоритм хорошо работает при целых или больших коэффициентах увеличения. 

Но резкие границы размываются. Для уменьшения изображения этот алгоритм также не подходит. 

Фрагмент кода алгоритма бикубической интерполяции:

Begin

bmp1:=TBitmap.Create; bmp1.Width:=bmp.Width;bmp1.Height:=bmp.height;

//------------------------------------------------------------------------

For j:=0 to bmp.Height do //Преобразование только по горизонтали

begin

For i:=0 to Round(bmp.Width/2) do

begin

i_new:=(i*2); //по номеру пикселя i в новом (формируемом) изображении находим номер i_new в исходном изображении

dx:=0.5;//Это смещение (сдвиг) весовой функции

R:=0; G:=0; B:=0; s:=0;

For k:=-1 to 2 do//яркость пикселя с номером i равна сумме яркостей этого пикселя, соседа слева и двух соседей справа, умноженных на весовые коэффициенты

Begin

S:=i_new+k;//Это просто для удобства

If s<0 then s:=0; If s>bmp.Width-1 then s:=bmp.Width-1;

R:=R+GetRValue(bmp.Canvas.Pixels[(s),j])*fR(k-dx);

G:=G+GetGValue(bmp.Canvas.Pixels[(s),j])*fR(k-dx);

B:=B+GetBValue(bmp.Canvas.Pixels[(s),j])*fR(k-dx);

If R>255 then R:=255; If R<0 then R:=0;

If G>255 then G:=255; If G<0 then G:=0;

If B>255 then B:=255; If B<0 then B:=0;

End;

//В выходном изображении дублируем каждый второй столбец

bmp1.Canvas.Pixels[i*2,j]:=RGB(Round(R),Round(G),Round(B));

bmp1.Canvas.Pixels[i*2+1,j]:=RGB(Round(R),Round(G),Round(B));

end;{For i}

Form3.Caption := IntToStr(round(100 * j/ bmp.Height)) + '%';

Application.ProcessMessages;

if Application.Terminated then

Exit;

end;

Яркость пикселя нового изображения находится как сумма яркостей соответствующего пикселя старого изображения и трех его соседей (один сосед слева и два - справа), умноженных на значения весовой функции.

Чтобы новое изображение не сжималось по горизонтали в два раза, я его расширяла методом ближайшего соседа - три строки в конце подпрограммы.

Экспериментальным путем подобраны коэффициенты весовой функции. Если разрешить использовать подобранные коэффициенты, то бикубическая интерполяция получается максимально похожей как в Фотошопе.

Выводы к главе II:

В этой главе приведено общее описание технологии выполнения разработки. В первом параграфе главы приведены описания инструментария для разработки, основных использованных компонентов. Во втором параграфе главы построена логическая схема разрабатываемого продукта – пошаговое описание технологии выполнения.