Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Масштабирование изображения

Delphi , Графика и Игры , Изображения

Масштабирование изображения

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{ 
  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;

Привет! Я перевёл текст на русский язык:

Основной рутин Процедура MakeThumbNail принимает два параметра: src (оригинальное изображение) и dest (назначенное изображение). Она сначала проверяет, является ли исходное изображение уже достаточно маленьким, в котором случае она просто присваивает исходное изображение назначенному. Если нет, то она продолжает процесс resize.

Масштабирование Код рассчитывает масштабные коэффициенты для оси x (xscale) и y (yscale) на основе размера оригинального изображения и желаемого размера миниатюры. Затем он создает два таблицы-lookup (lutX и lutY) для хранения этих масштабных коэффициентов.

Resize Процедура проходит по каждой строке назначенного изображения и для каждого пикселя в этой строке рассчитывает соответствующие значения пикселей из оригинального изображения с помощью таблиц-lookup. Результаты хранятся в назначенном изображении.

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

Восстановление кода 1. Производительность: Код использует таблицы-lookup (lutX и lutY) для ускорения процесса масштабирования, что является отличной оптимизацией. 2. Обработка изображений: Фильтр для улучшения деталей изображения можно улучшить с помощью болееadvanced алгоритма или применения фильтров в других направлениях (например, вертикальном или диагональном). 3. Обработка ошибок: Код предполагает, что входные изображения являются валидными и не обрабатывает ошибки или исключения. Было бы полезно добавить механизмы обработки ошибок для обеспечения надежности. 4. Читаемость кода: Код довольно плотный, с множеством переменных и расчетов. Рекомендуется разбить его на более маленькие функции или использовать более описательные имена переменных для улучшения читаемости.

Альтернативное решение Модерное альтернативное решение может заключаться в использовании библиотеки графических операций, таких как OpenImageIO или FreeImage, которые предоставляют встроенную поддержку resize и фильтрации изображений. Эти библиотеки могут обрабатывать различные форматы и обеспечивать лучшую производительность, чем custom-implementation.

Масштабирование изображения: код на Delphi для создания.thumbnail компонента.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Изображения ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:46:32/0.0059480667114258/1