Масштабирование изображения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 прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: Изображения ::
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |