Найбільш швидко змінити розмір bitmap-а (зменшити)

Найбільш швидко змінити розмір Bitmap-а (зменшити).

> Це відсікання, а не масштабування.

неправда. це
> Найшвидше змінити розмір Bitmap-а?

а якщо міняти картинку, то залежить від алгоритму.


> Неправда. це

Я не дивився реалізацію TBitmap.Width: =. і TBitmap.Height: =. в VCL, але щось мені підказує, що за ними ховається той же StretchBlt :)
Це навряд чи швидше.

з під вінди апаратно прискорений є bltfast на прямому WinApi, але масштабування він не тримає.
до того ж там вагон параметрів в типі TBltFx з поганою документацією.

так що так, діректдрав. можна через Дельфах, можна через заголовки.
Але якщо це одинична операція, то завантаження бітмапами в поверхню, потім масштабування, потім вивантаження назад займе стільки часу, що ні про яке прискоренні і мови йти не може.


> Тільки все ж TBitmap.Width: =. і TBitmap.Height: = Не
> Масштабують - вони обрізають зайве

якщо через TImage і включено Strecth, то масштабують

Подивися GraphicEx, там кілька способів масшабірованія, може буде швидше.


> Але розмір вони змінюють, що і було потрібно в сабже.

Буквоїдство це. У тому ж сабже вказано StretchBlt. Мова про масштабування. Російська мова багатий і неоднозначний.

StretchBlt потрібно з фільтрацією або без?
Якщо з фільтрацією, FastLIB "івський Bilinear швидше, хоча і дає кілька гіршу якість (мабуть, сам алгоритм простіше). Якщо без (FastResize) - швидкість приблизно та ж, що і у StretchBlt.
Щодо одиничних операцій - так, від DDraw в такій ситуації буде мало користі. Хіба що зберігати в тому розмірі, який прийшов, і робити stretch безпосередньо при виведенні.


> StretchBlt потрібно з фільтрацією або без?

Чи не фільтрація необов'язкова.
Тобто
SetStretchBltMode (Canvas.Handle, COLORONCOLOR); для StretchBlt

Вобщем я прийшов до висновку, що не обігнати StretchBlt.
Спробував і DrawDibDraw () і INTEL Image Processing Library - все повільніше, ніж StretchBlt з COLORONCOLOR;

Результат для 100 повторів на деякій зображенні:

StretchBlt - 281 тиків
DrawDibDraw - 625 тиків (хоча це швидше підготовчі операції)
INTEL Image Processing Library - 844 (теж підготовка довше, ніж обробка)

для StretchBlt # XA0; + HALFTONE - 1547 тиків.


> Sapersky # XA0; (21.11.06 14:47) [19]

Для FastResize результат - 79 тиків. Однак.

Швидше за все буде якщо на асемблері написати. Немогу точно сказати будетлі приріст від MXX і SSE потрібно пробувати.

Стандартна Bit / StretchBlt теж вже апаратно-прискорена на скільки це можливо

Апаратно-прискореної реалізації StretchBlt я ще не зустрічав. Див. Посилання на rsdn з [5] - там людина пише, що теоретично її можна прискорити, але практично, з мого досвіду, виробники драйверів чомусь цього не роблять. Для підтвердження досвіду я викладав приклад - хоча швидкість він іноді міряє криво, перевага DirectDraw в stretch по ньому видно неозброєним оком.

Взагалі FastDIB зручніше у використанні, ніж стандартний TBitmap з VCL

Угу, я вже майже забув, що таке TBitmap :)
Хоча є у FastLIB і свої недоліки, слабка стійкість до помилок, наприклад (крок вліво, крок вправо - AV).

до слова у мене StretchBlt + HALFTONE працює набагато швидше і менше жере проц, ніж інші режими StretchBlt.
чому? сам не знаю.

У сенсі, вони ще більше будуть гальмувати, ніж з фірмовими драйверами? Ну це само собою, але я не про те. Я про те, що якісь фірмові драйвера ні став, StretchBlt все одно буде працювати принаймні частково софтверного. Тобто повільніше surface.Blt.

до слова у мене StretchBlt + HALFTONE працює набагато швидше і менше жере проц, ніж інші режими StretchBlt.

може вказувати на те, що чудеса іноді трапляються :) Справа в тому, що у всіх # XA0; апаратних реалізаціях DirectDraw-stretch, які я бачив, HALFTONE прошитий намертво і ніяк не відключається (хоча це не зовсім те, що софтверний HALFTONE, якість трохи гірша). Тобто якщо HALFTONE швидше, StretchBlt в цьому випадку, можливо, працює апаратно.

DDraw майже в 3 рази повільніше FastDIB через довгої завантаження Bitmap-a.
Якщо без завантаження то раз в 5 швидше.

> Подивися GraphicEx, там кілька способів масшабірованія, може буде швидше.

У них дуже хороші алгоритми, до речі. Рекомендую. У себе з них переписаний на АСМ робив для великих зображень.

Найшвидший спосіб:
будується матриця координат, два масиви ліній виходить зображення в координатах вихідного. Тобто звідки брати точки з вихідного масиву.
Далі йдуть вкладені цикли по осі х, і у, для кожної лінії х і у вибираються згідно попередньо розрахованим координатам точки з вихідного бітмапами-сировини.
Швидкість дуже висока, mmx / sse тут не допоможе, тому що вважати особливо нічого, тільки пересилання.
Якість, звичайно, від швидкості страждає, але в моєму випадку, працюючи з великими картинками не критично, у мене зображення досить монотонні (або як це сказати)? Відкидання 3/4 точок майже не помітно.
Є у них же схожі алгоритми, але зі згладжуванням.

Десь у вас помилка в тесті. На моєму комп'ютері StretchBlt швидше, ніж FastResize, мало не на порядок. Навіть з інтерполяцією. Це за умови, що отрисовка відбувається відразу на екран, а якщо на інший Bitmap, то швидкості повинні бути приблизно однаковими.

А використання DirectX не для ігор мало коли виправдано, не в останню чергу через питання сумісності имхо.

FastResize не виводить на екран - вона з бітмапами на бітмапами масштабує.
Після результуючий бітмапами треба BitBlt куди треба.


> Sapersky # XA0; (28.11.06 19:50) [38]

Прикрути ще DrawDIBDraw з vfw:


procedure DDDraw (Canvas: TCanvas; dTop, dLeft, dHeight, dWidth: Integer;
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; Bitmap: TBitmap);
var
# XA0; lpBits # XA0 ;: Pointer;
# XA0; pBmpInfo: PBitmapInfo;
# XA0; nColors. Cardinal;
# XA0; hdd # XA0; # XA0 ;. HDRAWDIB;
# XA0; BitmapStream: TMemoryStream;

# XA0; procedure SetSize;
# XA0; var
# XA0; # XA0; RatioH,
# XA0; # XA0; RatioW # XA0 ;: Extended;
# XA0; begin
# XA0; # XA0; with pBmpInfo ^ .bmiHeader do begin
# XA0; # XA0; # XA0; if (biWidth> dWidth) or (biHeight> dHeight) then
# XA0; # XA0; # XA0; # XA0; begin
# XA0; # XA0; # XA0; # XA0; # XA0; RatioH: = dHeight / biHeight;
# XA0; # XA0; # XA0; # XA0; # XA0; RatioW: = dWidth # XA0; / biWidth;
# XA0; # XA0; # XA0; # XA0; # XA0; if RatioH> RatioW then RatioH: = RatioW;
# XA0; # XA0; # XA0; # XA0; # XA0; dHeight: = Trunc (biHeight * RatioH);
# XA0; # XA0; # XA0; # XA0; # XA0; dWidth # XA0;: = Trunc (biWidth # XA0; * RatioH);
# XA0; # XA0; # XA0; # XA0; # XA0; Exit;
# XA0; # XA0; # XA0; # XA0; end;
# XA0; # XA0; # XA0; dHeight: = biHeight;
# XA0; # XA0; # XA0; dWidth # XA0;: = biWidth;
# XA0; # XA0; end;
# XA0; end;

begin
# XA0; if Bitmap = nil then exit;
# XA0; BitmapStream: = TMemoryStream.Create;
# XA0; Bitmap.SaveToStream (BitmapStream);
# XA0; pBmpInfo: = PBitmapInfo (PChar (BitmapStream.Memory)
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; + SizeOf (TBitmapFileHeader));
# XA0; with pBmpInfo ^, bmiHeader do begin
# XA0; # XA0; if biClrUsed = 1 then
# XA0; # XA0; # XA0; nColors: = biClrUsed
# XA0; # XA0; else
# XA0; # XA0; # XA0; nColors: = (1 shl biBitCount);
# XA0; # XA0; if biBitCount> 8 then
# XA0; # XA0; # XA0; begin
# XA0; # XA0; # XA0; # XA0; lpBits: = PChar (@bmiColors) + Ord (biClrUsed)
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; + Ord (biCompression = BI_BITFIELDS) * 3;
# XA0; # XA0; # XA0; end
# XA0; # XA0; else lpBits: = PChar (@bmiColors) + nColors;
# XA0; # XA0; hdd: = DrawDibOpen;
# XA0; # XA0; try
# XA0; # XA0; # XA0; DrawDibRealize (hdd, Canvas.Handle, True);
# XA0; # XA0; # XA0; SetSize;
# XA0; # XA0; # XA0; DrawDibDraw (hdd,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; Canvas.Handle,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; dLeft, # XA0; dTop,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; dWidth, dHeight,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; PBitmapInfoHeader (@bmiHeader),
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; lpBits,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; 0, 0,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; biWidth, biHeight,
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; DDF_HALFTONE);
# XA0; # XA0; finally
# XA0; # XA0; # XA0; DrawDibClose (hdd);
# XA0; # XA0; end;
# XA0; end;
# XA0; BitmapStream.Free;
end;

Ще INTEL Image Processing Library теж. Буде корисна весчь.


> Зараз виявив, що швидкість StretchBlt з COLORONCOLOR
> Має не цілком очевидну залежність від глибини кольору

Нічого собі. А я і не знав.

> Щоб одночасно все-все порівняти, прикрутив FastLIB до
> Своєму тесту:

Перевірив у себе. Результати такі:

Stretchblt + 24bpp = 27004
FastLib + 24bpp = 10381

Stretchblt + 32bpp = 6219
FastLib + 24bpp = 8258

> [28] Sapersky # XA0; (24.11.06 14:57)


> StretchBlt все одно буде працювати принаймні частково
> Софтверного.

будь-яка функція працює частково софтверного, а саме перетворення картинки на сучасних видюхи - апаратне.
щодо StretchBlt, ось теж тест накатав

uses
# XA0; SysUtils,
# XA0; Windows,
# XA0; Graphics;

const
# XA0; INTER_COUNT = 10;

var
# XA0; bmpScreen, bmpDest: TBitmap;
# XA0; I: Integer;
# XA0; dt: TDateTime;

1280x1024x32bit (ati x600 winxp)


> Sapersky # XA0; (29.11.06 17:24) [44]

А що у нас так результати різняться сильно? Дозвіл різний?

Так, там було 800 * 600.
Для 1280 * 1024 * 32:

FastLIB: # XA0; 24: 9231; # XA0; 32: 7982
StretchBlt: 24: 42744 32: 5523

171 і 407.
Але це цілком передбачувано, цікаво наскільки швидше (чи швидше?) HALFTONE при виведенні на екран. Спробуй моїм тестом, не тільки StretchBlt / FastLIB, а й DirectDraw (DD Blt - stretch). І напиши яка конфігурація.

щодо версії компілятора підправив, але

Const
# XA0; FormatVars. array [0..3] of TPixelFormat =
# XA0; # XA0; (pfDevice, pf8bit, pf24bit, pf32bit);
# XA0; FormatBpps. array [0..3] of Integer =
# XA0; # XA0; (4, 1, 3, 4);
.
FormatBpps [0]: = GetDeviceCaps (DC, BITSPIXEL) shr 3;

як ТАКЕ взагалі у кого-то скомпілілось?

DD Blt - stretch - 849 (5892 mb / s)
(Q: 7159; T: 7160; C: 8437)

скомпіліл, замінивши Const на var.

1280x1024x32. Athlon64 3000+, 1 GB RAM.

DD Blt - stretch - 1512 (3306 mb / s)

GDI StretchBlt:
32: 5680 (880 mb / s)

GDI StretchBlt:
24. 17990 (208 mb / s)

FastLIB:
32: 3720 (1344 mb / s)

як ТАКЕ взагалі у кого-то скомпілілось?

У D5 типізовані константи за замовчуванням можна змінювати.
Починаючи, начебто, з D6 або 7 - за замовчуванням можна, але можна включити якесь опцією компілятора.

+1152 * 864, WinXP_SP2, PIV4 3GHz / 1Gb / GF7600GT

DD Blt - stretch - 430 (8835 mb / s)
(Q: 2360; T: 2361; C: 5492)

+1152 * 864, Vista b.6000, PIV4 3GHz / 1Gb / GF7600GT

> [51] Sapersky # XA0; (30.11.06 12:55)

причину, по якій у мене HALFTONE набагато економічніше і швидше я зрозумів, насправді, HALFTONE дійсно повільніше, але в моєму випадку - набагато швидше - це пов'язано з різною поведінкою функції при промальовуванні в WM_PAINT, до сабжу відношення не має)


> [44] Sapersky

> Тому, або зчитувати, але робити постояную перевірку для
> Уникнення AV, або зчитувати побайтно.
Формат зберігання: дібов в пямяти декларарует довжину кожної лінніі крутного 4-м байтам, так що як і читай, нарватся не вийде. Навіть з наступною рядки пиксель не схопити.

М-да, результати Вісти не вражають, але ж обіцяли прискорити все будь-яке.
Хоча краще, напевно, почекати офіційного релізу і нормальних драйверів, і тоді вже робити висновки.

Це не я писав, але відповім :)
По-перше, кратна 4-м байтам довжина рядка не гарантує наявність "хвоста" в кінці скан-лінії. По-друге, AV зловити складно ще й через те, що CreateDIBSection виділяє пам'ять з запасом, округлює до 4 кб по всій видимості. Але знову ж таки можна "вдало" підгадати з розміром і вилетіти-таки.
Тому запобіжні заходи потрібні, необов'язково постійна перевірка - можна зробити цикл по Width-1 пикселям для dword, а останній скопіювати побайтно.
Але все це не має значення, тому що з мого досвіду (див. [44] ще раз) особливої ​​переваги використання dword не дає.


> Хоча краще, напевно, почекати офіційного релізу і нормальних
> Драйверів, і тоді вже робити висновки.

Офіційний реліз у мене є. Драйвера теж нормальні. Повільніше Vista.