![]() |
![]() ![]() ![]() ![]() |
|
Масштабирование изображенияDelphi , Графика и Игры , ИзображенияМасштабирование изображения
Оформил: DeeCo
{
Here is the routine I use in my thumbnail component and I belive it is quite
fast.
A tip to gain faster loading of jpegs is to use the TJpegScale.Scale
property. You can gain a lot by using this correct.
This routine can only downscale images no upscaling is supported and you
must correctly set the dest image size. The src.image will be scaled to fit
in dest bitmap.
}
const
FThumbSize = 150;
//Speed up by Renate Schaaf, Armido, Gary Williams...
procedure MakeThumbNail(src, dest: tBitmap);
type
PRGB24 = ^TRGB24;
TRGB24 = packed record
B: Byte;
G: Byte;
R: Byte;
end;
var
x, y, ix, iy: integer;
x1, x2, x3: integer;
xscale, yscale: single;
iRed, iGrn, iBlu, iRatio: Longword;
p, c1, c2, c3, c4, c5: tRGB24;
pt, pt1: pRGB24;
iSrc, iDst, s1: integer;
i, j, r, g, b, tmpY: integer;
RowDest, RowSource, RowSourceStart: integer;
w, h: integer;
dxmin, dymin: integer;
ny1, ny2, ny3: integer;
dx, dy: integer;
lutX, lutY: array of integer;
begin
if src.PixelFormat <> pf24bit then src.PixelFormat := pf24bit;
if dest.PixelFormat <> pf24bit then dest.PixelFormat := pf24bit;
w := Dest.Width;
h := Dest.Height;
if (src.Width <= FThumbSize) and (src.Height <= FThumbSize) then
begin
dest.Assign(src);
exit;
end;
iDst := (w * 24 + 31) and not 31;
iDst := iDst div 8; //BytesPerScanline
iSrc := (Src.Width * 24 + 31) and not 31;
iSrc := iSrc div 8;
xscale := 1 / (w / src.Width);
yscale := 1 / (h / src.Height);
// X lookup table
SetLength(lutX, w);
x1 := 0;
x2 := trunc(xscale);
for x := 0 to w - 1 do
begin
lutX[x] := x2 - x1;
x1 := x2;
x2 := trunc((x + 2) * xscale);
end;
// Y lookup table
SetLength(lutY, h);
x1 := 0;
x2 := trunc(yscale);
for x := 0 to h - 1 do
begin
lutY[x] := x2 - x1;
x1 := x2;
x2 := trunc((x + 2) * yscale);
end;
dec(w);
dec(h);
RowDest := integer(Dest.Scanline[0]);
RowSourceStart := integer(Src.Scanline[0]);
RowSource := RowSourceStart;
for y := 0 to h do
begin
dy := lutY[y];
x1 := 0;
x3 := 0;
for x := 0 to w do
begin
dx:= lutX[x];
iRed:= 0;
iGrn:= 0;
iBlu:= 0;
RowSource := RowSourceStart;
for iy := 1 to dy do
begin
pt := PRGB24(RowSource + x1);
for ix := 1 to dx do
begin
iRed := iRed + pt.R;
iGrn := iGrn + pt.G;
iBlu := iBlu + pt.B;
inc(pt);
end;
RowSource := RowSource - iSrc;
end;
iRatio := 65535 div (dx * dy);
pt1 := PRGB24(RowDest + x3);
pt1.R := (iRed * iRatio) shr 16;
pt1.G := (iGrn * iRatio) shr 16;
pt1.B := (iBlu * iRatio) shr 16;
x1 := x1 + 3 * dx;
inc(x3,3);
end;
RowDest := RowDest - iDst;
RowSourceStart := RowSource;
end;
if dest.Height < 3 then exit;
// Sharpening...
s1 := integer(dest.ScanLine[0]);
iDst := integer(dest.ScanLine[1]) - s1;
ny1 := Integer(s1);
ny2 := ny1 + iDst;
ny3 := ny2 + iDst;
for y := 1 to dest.Height - 2 do
begin
for x := 0 to dest.Width - 3 do
begin
x1 := x * 3;
x2 := x1 + 3;
x3 := x1 + 6;
c1 := pRGB24(ny1 + x1)^;
c2 := pRGB24(ny1 + x3)^;
c3 := pRGB24(ny2 + x2)^;
c4 := pRGB24(ny3 + x1)^;
c5 := pRGB24(ny3 + x3)^;
r := (c1.R + c2.R + (c3.R * -12) + c4.R + c5.R) div -8;
g := (c1.G + c2.G + (c3.G * -12) + c4.G + c5.G) div -8;
b := (c1.B + c2.B + (c3.B * -12) + c4.B + c5.B) div -8;
if r < 0 then r := 0 else if r > 255 then r := 255;
if g < 0 then g := 0 else if g > 255 then g := 255;
if b < 0 then b := 0 else if b > 255 then b := 255;
pt1 := pRGB24(ny2 + x2);
pt1.R := r;
pt1.G := g;
pt1.B := b;
end;
inc(ny1, iDst);
inc(ny2, iDst);
inc(ny3, iDst);
end;
end;
Привет! Я перевёл текст на русский язык: Основной рутин
Процедура Масштабирование
Код рассчитывает масштабные коэффициенты для оси x ( Resize Процедура проходит по каждой строке назначенного изображения и для каждого пикселя в этой строке рассчитывает соответствующие значения пикселей из оригинального изображения с помощью таблиц-lookup. Результаты хранятся в назначенном изображении. Увеличение (опционально) Если высота миниатюры больше 2, код применяет фильтр для улучшения деталей изображения. Это涉гает проходить по каждому пикселю в миниатюре и рассчитывать новые значения пикселей на основе окружающих пикселей. Восстановление кода
1. Производительность: Код использует таблицы-lookup ( Альтернативное решение Модерное альтернативное решение может заключаться в использовании библиотеки графических операций, таких как OpenImageIO или FreeImage, которые предоставляют встроенную поддержку resize и фильтрации изображений. Эти библиотеки могут обрабатывать различные форматы и обеспечивать лучшую производительность, чем custom-implementation. Масштабирование изображения: код на Delphi для создания.thumbnail компонента. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш :: Главная :: Изображения ::
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 | ||||