Nadesłany przez Tomasz Lubiński, 03 kwietnia 2006 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Zmiana wielkosci obrazu - Bilinear Interpolation - Delphi/BI.pas:
// Zmiana wielkosci obrazka - // Algorytm Bilinear Interpolation - algorytm interpolacji podwójnej // www.algorytm.org // Tomasz Lubinski (c) 2006 unit BI; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ExtCtrls, StdCtrls, Math; type PPixelRec = ^TPixelRec; TPixelRec = packed record B: Byte; G: Byte; R: Byte; Reserved: Byte; end; TForm1 = class(TForm) src: TImage; dst: TImage; Label1: TLabel; Label2: TLabel; Edit1: TEdit; Label3: TLabel; Edit2: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); function Bilinear_Inter(x, y: Double): TPixelRec; function Inter(f1, f2, d: Double): Double; private { Private declarations } public { Public declarations } end; var Form1: TForm1; org: Array [1..122] of Array [1..100] of TPixelRec; implementation {$R *.DFM} function TForm1.Inter(f1, f2, d: Double): Double; begin Result := f1*(1-d) + f2*d; end; function TForm1.Bilinear_Inter(x, y: Double): TPixelRec; var x0,y0,x0_1, y0_1 : Integer; dx,dy : Double; begin x0 := Floor(x); y0 := Floor(y); dx := x-x0; dy := y-y0; if (x0 + 1 > src.Width) then x0_1 := x0 else x0_1 := x0 + 1; if (y0 + 1 > src.Width) then y0_1 := y0 else y0_1 := y0 + 1; Result.r := Round(Inter(Inter(org[x0, y0].R, org[x0_1, y0].R, dx), Inter(org[x0, y0_1].R, org[x0_1, y0_1].R, dx), dy)); Result.g := Round(Inter(Inter(org[x0, y0].G, org[x0_1, y0].G, dx), Inter(org[x0, y0_1].G, org[x0_1, y0_1].G, dx), dy)); Result.b := Round(Inter(Inter(org[x0, y0].B, org[x0_1, y0].B, dx), Inter(org[x0, y0_1].B, org[x0_1, y0_1].B, dx), dy)); end; procedure TForm1.Button1Click(Sender: TObject); var i,j: Integer; ratiox, ratioy : Double; pixel: PPixelRec; begin //pobierz wartosci pliku wejsciowego src.Picture.Bitmap.PixelFormat := pf32Bit; for j:= 1 to src.Height do begin pixel := src.Picture.Bitmap.ScanLine[j-1]; for i:=1 to src.Width do begin org[i][j] := pixel^; Inc(pixel); end; end; //pobierz nowy rozmiar dst.Width := StrToInt(Edit2.Text); dst.Height := StrToInt(Edit1.Text); dst.Picture.Bitmap := TBitmap.Create; dst.Picture.Bitmap.Width := dst.Width; dst.Picture.Bitmap.Height := dst.Height; ratiox := (src.Width-1)/(dst.Width-1); ratioy := (src.Height-1)/(dst.Height-1); //przygotuj obraz wynikowy dst.Canvas.Brush.Color := clWhite; dst.Canvas.Rectangle(0, 0, dst.Width, dst.Height); dst.Picture.Bitmap.PixelFormat := pf32Bit; for j:= 1 to dst.Height do begin pixel := dst.Picture.Bitmap.ScanLine[j-1]; for i:=1 to dst.Width do begin pixel^ := Bilinear_Inter((i-1)*ratiox+1, (j-1)*ratioy+1); Inc(pixel); end; end; end; end.