уменьшение/ увеличение зображения
От: zuv  
Дата: 21.06.05 07:11
Оценка: :)
Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: уменьшение/ увеличение зображения
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 21.06.05 09:59
Оценка:
Hello zuv, you wrote:

> Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


В сети полно графических библиотек. Например, FastLib.

--
Всего хорошего, Слава
Posted via RSDN NNTP Server 1.9
Re: уменьшение/ увеличение зображения
От: WondeRu Россия http://directshow.wonderu.com/
Дата: 21.06.05 11:21
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


Не городим огород, а используем стандартную функцию StretchBlt
----------
http://directshow.wonderu.com — DirectShow по-русски (статьи, форум)
Re[2]: уменьшение/ увеличение зображения
От: Аноним  
Дата: 22.06.05 05:10
Оценка:
Здравствуйте, WondeRu, Вы писали:

WR>Здравствуйте, zuv, Вы писали:


zuv>>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


WR>Не городим огород, а используем стандартную функцию StretchBlt

Мой опыт применения этой функции показал,что не стоит ей пользоваться.Она сильно искажает изображение.
Re[2]: уменьшение/ увеличение зображения
От: zuv  
Дата: 22.06.05 08:21
Оценка:
Здравствуйте, WondeRu, Вы писали:

Получается изображение чернобелое и очень плохого качества. В чем ошибка?

    LPBITMAPINFO lpbmi;  // Здесь хранится DIB картинка
    int oldwidth = lpbmi->bmiHeader.biWidth;
    int oldheight =lpbmi->bmiHeader.biHeight;
    DibBits((LPBITMAPINFOHEADER) lpbmi);

    HDC hDestDC=CreateCompatibleDC(0);
    SetStretchBltMode(hDestDC, HALFTONE);
    HDC hSourceDC=CreateCompatibleDC(0);
    SetStretchBltMode(hSourceDC, HALFTONE);
    HBITMAP hBmpold=CreateCompatibleBitmap(hSourceDC,oldwidth,oldheight);
    ::SetDIBits(hSourceDC, hBmpold, 0, oldheight,DibBits((LPBITMAPINFOHEADER) lpbmi), lpbmi, DIB_RGB_COLORS);
    HBITMAP hBmpnew=CreateCompatibleBitmap(hDestDC,width,height);
    HANDLE hNewBitmap=SelectObject(hDestDC,hBmpnew);
    HANDLE hOldBitmap=SelectObject(hSourceDC,hBmpold);

    StretchBlt(hDestDC,0,0, width, height, hSourceDC, 0,0, oldwidth, oldheight, SRCCOPY);

    SelectObject(hSourceDC,hOldBitmap);
    HBITMAP hBmp = (HBITMAP)SelectObject(hDestDC,hNewBitmap);
    
    BITMAPINFO pbi;
    pbi = *lpbmi;
    pbi.bmiHeader.biHeight = height;
    pbi.bmiHeader.biWidth = width;
    pbi.bmiHeader.biSizeImage =((3 * width + 3) & ~3) * height;

    BYTE* pData = new BYTE[pbi.bmiHeader.biSizeImage];
    ::GetDIBits(hDestDC,
        hBmp,
        0,
        height,
        (void*)pData,
        &pbi,
        DIB_RGB_COLORS);

    GlobalUnlock(*hdib);
    GlobalFree(*hdib);
    *hdib = NULL;

    *hdib = GlobalAlloc(GPTR,pbi.bmiHeader.biSizeImage + pbi.bmiHeader.biSize);
    memcpy((*hdib), (void*)&pbi, pbi.bmiHeader.biSize);
    memcpy(DibBits((LPBITMAPINFOHEADER)(*hdib)), pData, pbi.bmiHeader.biSizeImage);

    delete pData;
    DeleteObject(hDestDC);
    DeleteObject(hSourceDC);
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[3]: уменьшение/ увеличение зображения
От: Денис Майдыковский Россия http://www.maydyk.com
Дата: 22.06.05 08:36
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Получается изображение чернобелое и очень плохого качества. В чем ошибка?


В этом:
zuv>
zuv>    SetStretchBltMode(hDestDC, HALFTONE);
zuv>


After setting the HALFTONE stretching mode, an application must call the SetBrushOrgEx function to set the brush origin. If it fails to do so, brush misalignment occurs.

This option is not supported on Windows 95/98/Me.


Или устанавливать флаг COLORONCOLOR, результат будет похуже, но зато код совместимый.
Re[4]: уменьшение/ увеличение зображения
От: zuv  
Дата: 22.06.05 08:55
Оценка:
Здравствуйте, Денис Майдыковский, Вы писали:

ДМ>Здравствуйте, zuv, Вы писали:


zuv>>Получается изображение чернобелое и очень плохого качества. В чем ошибка?


ДМ>В этом:

zuv>>
zuv>>    SetStretchBltMode(hDestDC, HALFTONE);
zuv>>


ДМ>

ДМ>After setting the HALFTONE stretching mode, an application must call the SetBrushOrgEx function to set the brush origin. If it fails to do so, brush misalignment occurs.

ДМ>This option is not supported on Windows 95/98/Me.


ДМ>Или устанавливать флаг COLORONCOLOR, результат будет похуже, но зато код совместимый.


Установил COLORONCOLOR — не помогло. Картинка получается ужасной по качеству и черно-белой.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[3]: уменьшение/ увеличение зображения
От: arkhivania  
Дата: 22.06.05 09:20
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Получается изображение чернобелое и очень плохого качества. В чем ошибка?



zuv> HDC hDestDC=CreateCompatibleDC(0);


попробуйте ради интереса взять всё-таки реальный HDC окна для создания Compatible. когда-то у меня такое было, вроде проблема была в этом.
Re[3]: уменьшение/ увеличение зображения
От: programmater  
Дата: 23.06.05 17:30
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, WondeRu, Вы писали:


WR>>Здравствуйте, zuv, Вы писали:


zuv>>>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


WR>>Не городим огород, а используем стандартную функцию StretchBlt

А>Мой опыт применения этой функции показал,что не стоит ей пользоваться.Она сильно искажает изображение.

Хе, а ты как хотел? . Может я не правильно понял проблему, но по своему опыту могу сказать, что ресайз с дробными коэффициентами (это когда например 5 точек надо превратить в 3 и наоборот) — дело сложное и неблагодарное. И в таких случаях любой алгоритм, заточенный на скорость работы (а именно такой используется в StretchBlt), будет тупым по определению. Сам не пробовал, но думаю, что если тебе нужно качество, тебе прибется делать двумерное фурье-преобразование твоей картинки (что-то типа jpg или png) и потом делать обратное преобразование уже новых размеров. Только так имхо ты сможешь получить более-менее приличное качество ресайза при дробных коэффициентах.
Re: уменьшение/ увеличение зображения
От: korzhik Россия  
Дата: 23.06.05 19:02
Оценка: 6 (1)
Здравствуйте, zuv, Вы писали:

zuv>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


Вот тебе статья с основами: Bicubic Interpolation for Image Scaling

Существует много библиотек, которые реализует увеличение/уменьшение изображения.
Одна из них AntiGrain

Вот здесь демо, которое демонстрирует эти возможности.

Результаты работы:



Re[2]: уменьшение/ увеличение зображения
От: korzhik Россия  
Дата: 23.06.05 19:26
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Результаты работы:


K>


K>


Вот кстати здесь исходное изображение, чтоб можно было качество заценить
Re[2]: уменьшение/ увеличение зображения
От: Reunion  
Дата: 24.06.05 05:28
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Здравствуйте, zuv, Вы писали:


zuv>>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


K>Вот тебе статья с основами: Bicubic Interpolation for Image Scaling


Статья хорошая. А есть еще статьи по данной теме? Очень нуно...
Re: уменьшение/ увеличение зображения
От: Bluesman  
Дата: 24.06.05 05:48
Оценка:
Здравствуйте, zuv, Вы писали:

zuv>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


Посмотри исходники VirtualDub. Когда-то я там находил неплохой алгоритм уменьшения/ увеличения изображений и даже пользовался им некоторое время.
Re[4]: уменьшение/ увеличение зображения
От: Romul Россия  
Дата: 24.06.05 05:56
Оценка:
ИМХО не надо. Достаточно просто вычислять цвет по взвешенным коэффициентам

"programmater" <34509@users.rsdn.ru> сообщил/сообщила в новостях следующее: news:1238062@news.rsdn.ru...
From: programmater

Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, WondeRu, Вы писали:


WR>>Здравствуйте, zuv, Вы писали:


zuv>>>Если у кого есть киньте в меня алгоритмом изменения размера изображения. Срочно нужно.


WR>>Не городим огород, а используем стандартную функцию StretchBlt

А>Мой опыт применения этой функции показал,что не стоит ей пользоваться.Она сильно искажает изображение.

Хе, а ты как хотел? . Может я не правильно понял проблему, но по своему опыту могу сказать, что ресайз с дробными коэффициентами (это когда например 5 точек надо превратить в 3 и наоборот) — дело сложное и неблагодарное. И в таких случаях любой алгоритм, заточенный на скорость работы (а именно такой используется в StretchBlt), будет тупым по определению. Сам не пробовал, но думаю, что если тебе нужно качество, тебе прибется делать двумерное фурье-преобразование твоей картинки (что-то типа jpg или png) и потом делать обратное преобразование уже новых размеров. Только так имхо ты сможешь получить более-менее приличное качество ресайза при дробных коэффициентах.
Re[3]: уменьшение/ увеличение зображения Оценить
Posted via RSDN NNTP Server 1.9
Re[3]: уменьшение/ увеличение зображения
От: korzhik Россия  
Дата: 24.06.05 06:04
Оценка:
Здравствуйте, Reunion, Вы писали:


K>>Вот тебе статья с основами: Bicubic Interpolation for Image Scaling


R>Статья хорошая. А есть еще статьи по данной теме? Очень нуно...


К сожалению сейчас не могу помочь конкретными ссылками.
Re[3]: уменьшение/ увеличение зображения
От: McSeem2 США http://www.antigrain.com
Дата: 24.06.05 07:05
Оценка: 9 (1) :)
Здравствуйте, korzhik, Вы писали:
K>Вот кстати здесь исходное изображение, чтоб можно было качество заценить

Качество при уменьшении — сукъсь. В том примере используется просто фильтрация "как есть". Это быстро, но много цветовой информации проливается мимо тазика. Для уменьшения с хорошим качеством надо ресамплить, что существенно медленнее. Если взять исходное изображение, и уменьшить его примерно до размеров в предыдущем сообщении, то разница по скорости с- и без ресамплинга будет около 12 раз. Качество вот:
Regular filter:


Resample:


Не надо думать, что первое изображение типа "более четкое". Там действительно не хватает деталей — достаточно посмотреть на ошейник. Например, тонкая горизонтальная линия без ресамплинга может просто исчезнуть.

Более продвинутый пример:
http://antigrain.com/demo/image_resample.zip

Там можно выполнять еще и перспективные преобразования, например, из этого баскервильского монстра можно сделать вполне симпатичную таксу
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[4]: уменьшение/ увеличение зображения
От: korzhik Россия  
Дата: 24.06.05 07:15
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Там можно выполнять еще и перспективные преобразования, например, из этого баскервильского монстра можно сделать вполне симпатичную таксу

MS>

прикольно
кстати это не "баскервильный монстр", а мой милый пёсик Ричард... очень, кстати, добрый
Re[3]: уменьшение/ увеличение зображения
От: McSeem2 США http://www.antigrain.com
Дата: 24.06.05 21:28
Оценка: 9 (1)
Здравствуйте, Reunion, Вы писали:

R>Статья хорошая. А есть еще статьи по данной теме? Очень нуно...


Скорее всего страшный баян, но на всякий случай.
minorlogic постил отчет о мощном ислледовании фильтров.
http://www.rsdn.ru/Forum/Message.aspx?mid=1165444
Автор: minorlogic
Дата: 11.05.05

Еще вот есть сравнение фильтров с формулами:
http://www.path.unimelb.edu.au/~dersch/interpolator/interpolator.html
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[4]: уменьшение/ увеличение зображения
От: Reunion  
Дата: 25.06.05 04:26
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Здравствуйте, Reunion, Вы писали:


R>>Статья хорошая. А есть еще статьи по данной теме? Очень нуно...


MS>Скорее всего страшный баян, но на всякий случай.

MS>minorlogic постил отчет о мощном ислледовании фильтров.
MS>http://www.rsdn.ru/Forum/Message.aspx?mid=1165444
Автор: minorlogic
Дата: 11.05.05

Баян или не баян, но мимо меня прошел... Там линк на исходники битый. Может у кого есть, вышлите на
MS>Еще вот есть сравнение фильтров с формулами:
MS>http://www.path.unimelb.edu.au/~dersch/interpolator/interpolator.html
Хотелось бы побольше математики... и исходников...
Спасибо.
Re[5]: уменьшение/ увеличение зображения
От: McSeem2 США http://www.antigrain.com
Дата: 25.06.05 05:55
Оценка: 20 (3)
Здравствуйте, Reunion, Вы писали:

R>Хотелось бы побольше математики... и исходников...

R>Спасибо.

Математика там очень простая. Фильтр представляет собой функцию, симметричную относительно оси OY.
Для сравнения формы фильтров я даже написал специальную дему: http://antigrain.com/demo/image_fltr_graph.zip
Ну или еще вот: http://antigrain.com/demo/image_filters2.zip
Фильтр охватывает некую область, например, линейный фильтр — это +-1 пиксел, итого, 2x2, 4 пиксела. Теоретически, фильтр может быть бесконечным (например, функция Ланкоша), но на практике это не реально, поэтому ограничиваются неким окном, типа 16x16.
Теперь как это работает. Рассмотрим простой линейный фильтр. Его формула y=1-x, симметрично отображенная на отрицательные x. Диапазон x, он же радиус фильтра равен 1. Далее берем координату на исходном изображении с высокой точностью. Если координата попадает в точности на пиксел, то его и берем и больше нас ничего не интересует. Но это — редкий случай. Как правило, мы попадаем как-то типа пиксел +0.3. Это значит, что нам надо взять y=1-0.3 = 0.7 пиксела на который мы попали и остаток = 0.3 — от следующего пиксела. Таким образом, мы суммируем пикселы, попадающие в фильтр, взвесив их на значение этого фильтра. Теперь переходим к двум координатам и перемножаем значения фильтров для X и Y. Линейный фильтр очень наглядно представляется следующим образом. Вот у нас есть сетка из пикселов. Мы берем квадрат равный ячейке сетки и кладем его в произвольное место. В общем случае, наш квадрат перекрывает 4 пиксела. Эти 4 пиксела надо просуммировать с весами, пропорциональными площади перекрытия для каждого пиксела. Площадь перекрытия определяется как dx*dy перекрытия.
Теперь переходим от линейного фильтра к произвольному. Мы просто можем взять не расстояние dx, а значение функции от dx. Кроме того, фильтр сам по себе может иметь и больший радиус, например, классический бикубик охватывает область 4x4 пиксела. Мы просто все это суммируем с соответствующими весами.

Вот, например, кусок кода для суммирования:
    y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
    fg_ptr = (const value_type*)base_type::source_image().row(y_lr + start) + (x_lr + start) * 3;
    do
    {
        x_count = diameter;
        weight_y = weight_array[y_hr];
        x_hr = image_subpixel_mask - x_fract;

        do
        {
            int weight = (weight_y * weight_array[x_hr] + 
                         image_filter_size / 2) >> 
                         image_filter_shift;

            fg[0] += *fg_ptr++ * weight;
            fg[1] += *fg_ptr++ * weight;
            fg[2] += *fg_ptr++ * weight;

            x_hr += image_subpixel_size;

        } while(--x_count);

        y_hr += image_subpixel_size;
        fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - step_back);

    } while(--y_count);

    fg[0] >>= image_filter_shift;
    fg[1] >>= image_filter_shift;
    fg[2] >>= image_filter_shift;

    if(fg[0] < 0) fg[0] = 0;
    if(fg[1] < 0) fg[1] = 0;
    if(fg[2] < 0) fg[2] = 0;

    if(fg[0] > base_mask) fg[0] = base_mask;
    if(fg[1] > base_mask) fg[1] = base_mask;
    if(fg[2] > base_mask) fg[2] = base_mask;

Здесь, конечно много "шума", но мне просто лень все это отчищать
Конечно же, фильтр здесь используется не напрямую, а через предварительно вычисленную таблицу (LUT). И все значения — целочисленные, смасштабтрованные на "image_filter_size", что является степенью двойки.

Важное свойство фильтра — баланс сумм значений по пиксельному шагу. Как бы это получше объяснить. В общем, сумма значений с шагом 1 для всего фильтра должна быть 1. Если мы смещаемся на 0.1 пиксела, то сумма значений все равно должна оставаться 1. И так по всему диапазону 0...1. Если это условие не соблюдается, то изображение может темнеть или светлеть в зависимости от того, куда мы попали. Или например, при повороте оно может пойти пятнами.
http://www.rsdn.ru/Forum/Message.aspx?mid=1165832&amp;only=1
Автор: McSeem2
Дата: 12.05.05

http://antigrain.com/stuff/gaussian_rotate_effect.png

Другое важное свойство фильтра — если мы хотим, чтобы изображение не размывалось, то в точке 0 фильтр должен иметь значение 1. При этом, чтобы обеспечить предыдущее свойство, то в точках 1,2,3... должно быть значение 0 (для отрицательных X тоже). Не все фильтры этому соответствуют. Например, классический бикубик размывает изображение, даже в случае тождественных преобразований.

Таким образом, вся математика определяется собственно формой фильтра.
Наверное это все очень сумбурно, но просто поздно уже, умственный мозг устал, формулирует плохо
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.