Сохранение миниатюр [Готово]

Автор V0lt, 25 июня 2016, 10:52:34

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

V0lt

Есть два момента которые требуют улучшения:
1. Нельзя прервать процесс создания миниатюры. Как минимум должна быть возможность закрыть плеер.
2. Плохое качество миниатюр.
[merge_posts_bbcode]Добавлено: 2016-06-25 10:52:34[/merge_posts_bbcode]

По 1-у пункту. Хотелось бы некий универсальный механизм для завершения разных некритичных операций при закрытии плеера.

Aleksoid1978

Ну по поводу пункта 1 думаю не сложно добавить обработку нажатия клавиш, а лучше запускать в отдельном потоке и разруливать через евенты.
По поводу пункта 2 - тут надо переписать/заменить алгоритм уменьшения. Может надо использовать что-то из vd. Надо проверить.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Я думал о неком глобальном сообщении, проверку которого втравляем в цикл генерации миниатюр. Вроде что-то подобное у нас где-то используется.
Не стоит добавлять обработчик клавиш в SaveThumbnails.

Aleksoid1978

Ну и я сказал что евенты. Но тогда надо запускать в отдельном потоке - чтобы это дело обрабатывать. Это не трудно реализовать :)

По поводу качества - надо попробовать использовать BitBltFromRGBToRGBStretch(), с помощью этой функции уменьшать - а уже потом просто скопировать данные из полученных в общие.
[merge_posts_bbcode]Добавлено: 2016-06-25 18:43:09[/merge_posts_bbcode]

Проверил - использование BitBltFromRGBToRGBStretch() дает более "гладкую" картинку, более мягкую. Правда меня смущает вот этот кусок кода, не могу понять как просто данные перенести из полученной маленькой картинки в большую общую, в нужные координаты.
       for (DWORD h = r.bottom - r.top, y = 0, yd = (sh << 8) / h; h > 0; y += yd, h--) {
            DWORD yf = y & 0xff;
            DWORD yi = y >> 8;

            DWORD* s0 = (DWORD*)(src + (int)yi * sp);
            DWORD* s1 = (DWORD*)(src + (int)yi * sp + sp);
            DWORD* d  = (DWORD*)dst;

            for (DWORD w = r.right - r.left, x = 0, xd = (sw << 8) / w; w > 0; x += xd, w--) {
                DWORD xf = x & 0xff;
                DWORD xi = x >> 8;

                DWORD c0 = s0[xi];
                DWORD c1 = s0[xi + 1];
                DWORD c2 = s1[xi];
                DWORD c3 = s1[xi + 1];

                c0 = ((c0&0xff00ff) + ((((c1&0xff00ff) - (c0&0xff00ff)) * xf) >> 8)) & 0xff00ff
                     | ((c0&0x00ff00) + ((((c1&0x00ff00) - (c0&0x00ff00)) * xf) >> 8)) & 0x00ff00;

                c2 = ((c2&0xff00ff) + ((((c3&0xff00ff) - (c2&0xff00ff)) * xf) >> 8)) & 0xff00ff
                     | ((c2&0x00ff00) + ((((c3&0x00ff00) - (c2&0x00ff00)) * xf) >> 8)) & 0x00ff00;

                c0 = ((c0&0xff00ff) + ((((c2&0xff00ff) - (c0&0xff00ff)) * yf) >> 8)) & 0xff00ff
                     | ((c0&0x00ff00) + ((((c2&0x00ff00) - (c0&0x00ff00)) * yf) >> 8)) & 0x00ff00;

                *d++ = c0;
            }

            dst += dp;
        }
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Этот код тебе вообще не нужно трогать.

Aleksoid1978

Цитата: V0ltЭтот код тебе вообще не нужно трогать.

Еще как нужно - это как раз и есть оригинальный код ресайза :)
[merge_posts_bbcode]Добавлено: 2016-06-25 20:51:00[/merge_posts_bbcode]

Вот собранный билд + патч. Ресайз делается силами BitBltFromRGBToRGBStretch().
https://yadi.sk/d/2tm9lUyhsnHab

Правда что-то разницы в качестве я не заметил, но зато должно быть немного по шустрее делаться ресайз, все таки там используются различные оптимизации.

По поводу отмены создания миниатюр - тут есть нюанс, пока он выполняется не работает нажатия ни кнопок ни меню. Запустить в отдельном потоке тоже не получится - нам необходимо дождаться его окончания и только после что-то делать дальше.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Неожиданно. Мне подумалось что это тень. :)

Что-то твой билд еще хуже генерирует миниатюры.

Aleksoid1978

Что-то по поводу хуже я не заметил. Выложи свои файлики-миниатюр - с SVN и с моего билда. Гляну.
У себя я сохраняю только в .png
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt


Aleksoid1978

Ну сравнение на 8К - это уже перебор да и не актуально :) В любом случае ни там ни там ни чего не видно.

Вот сравнил на 4K
svn:


test:


А вот так нагляднее - http://screenshotcomparison.com/comparison/176601
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Не обязательно 8k, главное сильное уменьшение, просто на этом сэмпле видно разницу.
Да и особого ускорения от BitBltFromRGBToRGBStretch() не будет. Код который сейчас используется простой как валенок.

Aleksoid1978

Ну тогда закрываем тему - ни улучшить качество картинки, ни отменить создание миниатюр мы не сможем.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Все можем, только не сразу.

Aleksoid1978

Ну в принципе ты прав - погуглил и нашел несколько алгоритмов ресайза. Взял один из них и проверил качество, вот что вышло на 4K
http://screenshotcomparison.com/comparison/176605
более "смазанное", зато нет этих разломов, белых ломанных линий и т.д.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

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

PS: У меня синтаксис GDI мозг не принимает. Там во всех функциях нужно записать HDC, который порой вообще непонятно откуда брать, т.к. в примерах оно появляется волшебным образом. Да и название дебильное device context. :mad: