Графический эффект перехода одного изображения в другое.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 13:14

Добрый день уважаемые гуру и телепаты!
Возникла необходимость реализовать на VB графический эффект: есть 2 небольшие картинки, надо создать несколько промежуточных вариантов с помощью VB (чтобы потом их сохранить и прокручивать как кадры - чтобы было быстрее). Или более быстрый способ, чтобы трансформация происходила в реальном времени.
Т.е. имея первоначальную и конечную картинку нужно чтобы на глазах пользователя одна плавно переходила в другую. Пробовал сравнивать цвета пикселей по R G B и увеличивать/уменьшать эти значения в зависимости от разницы того же пиксела в картикне А и B, но видимо что то не допонимаю, получается фигня. ((
Прошу прощения за такое несколько невнятное объяснение, надеюсь смысл задачи удалось донести.
С уважением!
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Графический эффект перехода одного изображения в другое.

Сообщение Хакер » 05.07.2010 (Пн) 13:36

Цвет определённой точки промежуточного изображения получается путём линейной (не обязательно) интерполяции цветовых компонентов соотв. точки в исходном и целевом изображении.

Если получается фигня — значит в коде ошибки.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 14:07

Да, наверное дело в коде. Никогда не пробовал делать подобное, поэтому прошу прощения за свою некомпетентность. ((
Я делаю так - получаю по св-ву Point код цвета, получаю из него цвета R1 (биты 17-24), G1 (9-16) и B1 (1-8). Получаю то же самое R2, G2 и B2 для конечного цвета пикселя.
Сравниваю R1 с R2, G1 c G2 и B1 с B2. Если первое значение больше второго - уменьшаю на 1, а если больше - то увеличиваю на 1. Затем собираю полное значение и устанавливаю его для данного пикселя.

Код вот такой (я рисую примитивнейшим и тормозным способом - просто осваиваю работу с цветами в VB):

Код: Выделить всё
For f = 0 To fbox(0).Width
    For g = 0 To fbox(0).Height
        l = Picture1.Point(f, g)    'Pixel 1 code
        m = fbox(1).Point(f, g)     'Pixel 2 code
       
        Col1 = DecToBin(CStr(l))
        Col2 = DecToBin(CStr(m))
       
        R1 = Val(BinToDec(Mid(Col1, 17, 8)))
        G1 = Val(BinToDec(Mid(Col1, 9, 8)))
        B1 = Val(BinToDec(Mid(Col1, 1, 8)))
       
        R2 = Val(BinToDec(Mid(Col2, 17, 8)))
        G2 = Val(BinToDec(Mid(Col2, 9, 8)))
        B2 = Val(BinToDec(Mid(Col2, 1, 8)))
         
        If R1 > R2 Then R1 = R1 - 1
        If G1 > G2 Then G1 = G1 - 1
        If B1 > B2 Then B1 = B1 - 1
        If R1 < R2 Then R1 = R1 + 1
        If G1 < G2 Then G1 = G1 + 1
        If B1 < B2 Then B1 = B1 + 1
       
        Col1 = Val(BinToDec((DecToBin(CStr(R1)) + DecToBin(CStr(G1)) + DecToBin(CStr(B1)))))
        Picture1.PSet (f, g), Col1
2   Next g
Next f


Может есть какие-либо рабочие примеры, или готовые контролы, реализующие этот алгоритм?
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Графический эффект перехода одного изображения в другое.

Сообщение alibek » 05.07.2010 (Пн) 15:07

Особист писал(а):Если первое значение больше второго - уменьшаю на 1, а если больше - то увеличиваю на 1.

Почему на один?
На разница/шаги.
Lasciate ogni speranza, voi ch'entrate.

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 15:34

Alibek, подскажи пож-та разница между чем и чем, и как получить кол-во шагов?
В контексте приведённого примера к сожалению мне совсем не очевидно, помогите разобраться pls))
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Графический эффект перехода одного изображения в другое.

Сообщение iGrok » 05.07.2010 (Пн) 16:33

Особист писал(а):Alibek, подскажи пож-та разница между чем и чем, и как получить кол-во шагов?
В контексте приведённого примера к сожалению мне совсем не очевидно, помогите разобраться pls))

Ну ёпрст.. Средняя школа же!

знач_дельта = ( знач_кон - знач_нач ) / кол-во градаций.
кол-во градаций - плавность перехода. Задаёшь сам.

17, 96, 224 -> 208, 13, 21 (r, g, b)

Предположим, 100 шагов. i - номер шага
r = 17 + (208 - 17) / 100 * i
g = 96 + (13 - 96) / 100 * i
b = 224 + (21 - 224) / 100 * i
Последний раз редактировалось iGrok 05.07.2010 (Пн) 16:36, всего редактировалось 1 раз.
label:
cli
jmp label

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Графический эффект перехода одного изображения в другое.

Сообщение alibek » 05.07.2010 (Пн) 16:35

Особист писал(а):В контексте приведённого примера к сожалению мне совсем не очевидно, помогите разобраться pls))

Контекст приведенного примера не применим, потому что пример не имеет смысла. Из него непонятно, что ты хочешь.
Lasciate ogni speranza, voi ch'entrate.

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 17:48

Спасибо за разъяснения! Видимо я всех нечаянно заморочил, поэтому мы друг друга немножко не поняли. ((
Постараюсь более наглядно.

Приведённый код - это и есть один очередной шаг программы. Процедура пробегает по всем точкам и приближает на 1 значение каждого R, B и G к требуемому, если это необходимо. Процедура эта повторяется до тех пор, пока изображение не станет 1 в 1 как требуемое. Я её выложил чтобы показать, как я меняю цвет, паытаясь достичь плавного перехода. Который почему-то не достигается.
Я столкнулся с затруднением, которое попробую здесь проиллюстрировать.
Изображение

Но сейчас склоняюсь к тому, что на VB реализовать это именно так будет проблематично, видимо проще сделать анимированные гифки.
Напишите, пожалуйста, если я ошибаюсь. Эффект то довольно распространённый, м.б. имеются готовые контролы, реализующие этот принцип...
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Графический эффект перехода одного изображения в другое.

Сообщение Alec » 05.07.2010 (Пн) 19:24

Во-первых - работа с битами через строки - круто, но очень-очень медленно!
Особист писал(а):просто осваиваю работу с цветами в VB

Нет, для начало нужно освоить работу с типами данных, понять чем же они отличаются, разобраться с представлением чисел в памяти и тому подобное.
Во вторых - что, по-твоему, делает строка
Код: Выделить всё
Col1 = Val(BinToDec((DecToBin(CStr(R1)) + DecToBin(CStr(G1)) + DecToBin(CStr(B1)))))

Точнее - что должна делать, что делает, и что не делает?
PS.(offtop) А тетка с зеленой бородой получилась прикольно)))
Иногда лучше вовремя остановиться...
И начать заново!

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 20:31

Alec, строка как бы собирает значение цвета в decimal - устанавливает новые значения R,G и B.
Т.е. например новое зн-е R = 255, G = 1, B = 3. Результат будет преобразованная в Long 24-значная строка, "11111111" + "00000001" + "00000011", т.е. новое значение цвета заданного пикселя.
Могу приложить код функций, просто предполагаю, что и так понятно их назначение. Вкратце - на входе и на выходе String; отправляем "255" получаем "11111111" и наоборот.
Если о том, что НЕ должна - если ты имел ввиду сложение результатов, то т.к. это String, она всегда генерирует строку 24 символа, проверено. Можно + заменить на &.
Также теоретически допускаю, что если глубина цветов рабочего стола задана не 32 бита, то возможны разные глюки.

Я понимаю, что код неоптимизирован и реализуется очень тормозным способом, ну дык я хочу просто понять можно ли осуществить задуманное на VB или нет.
Потому что, если реализация желаемого возможна, я буду например сохранять 2-3 промежуточных изображения вместе с начальным и конечным и лепить из них анимированный ГИФ (ну или реализовывать собственный анимированный контрол, что в общем то несложно).
Применяемый мною метод превращения одного изображения в другой не работает так как задумано.
Поэтому вопрос - осуществимо ли такое на ВБ вообще (пусть и с тормозами) и что не так c алгоритмом?

PS: да, с тёлкой феерия какая-то ))
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Графический эффект перехода одного изображения в другое.

Сообщение Alec » 05.07.2010 (Пн) 20:58

Зачем так сложно?!
Чем не устраивает:
Код: Выделить всё
  R = Col And &HFF
  G = Col \ &H100 And &HFF
  B = Col \ &H10000 And &HFF

И (о, чудо!):
Код: Выделить всё
  Col=RGB(R,G,B)
Иногда лучше вовремя остановиться...
И начать заново!

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 21:05

AlecДа, согласен! :oops: Спасибо!
Честно говоря я только сёдня решил попробовать сделать граф. фильтр на VB, как в Кореле, не обладая знаниями в области преобразования чисел в VB.
Поэтому и пошёл неоптимальным путём. Теперь благодаря тебе я знаю об этом больше!
Но всё равно в результате получается то же, что и было (хоть и быстрей). В чём же может быть принципиальная ошибка алгоритма?
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Графический эффект перехода одного изображения в другое.

Сообщение Alec » 05.07.2010 (Пн) 21:07

Сколько раз выполняется приведенный тобой код?
Иногда лучше вовремя остановиться...
И начать заново!

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 21:16

Alec, всегда по-разному, т.к. неизвестно сколько раз нужно изменить цвет каждого пикселя, чтобы достигнуть конечного изображения.
Поэтому я предполагал реализовать счётчик или флаг, типа
1 count = 0
... начало цикла обработки
... если случилось изменить цвет пикселя, то count = count + 1
... конец цикла обработки
doevents 'это чтобы было видно результат и не зависало'
if count then goto 1

Но гонял код просто по нажатию кнопки, т.к. уже на 2-3 преобразованиях становилось понятно, что картинка рисуется не так, как задумано.
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Графический эффект перехода одного изображения в другое.

Сообщение iGrok » 05.07.2010 (Пн) 21:47

Особист, ты моё сообщение не прочитал, или из принципа на него внимания не обратил?
Алибек тебе чётко сказал, в чём ошибка в алгоритме. А я привел пример, как её исправить.
label:
cli
jmp label

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Графический эффект перехода одного изображения в другое.

Сообщение Alec » 05.07.2010 (Пн) 22:11

iGrok писал(а):Особист, ты моё сообщение не прочитал, или из принципа на него внимания не обратил?
Алибек тебе чётко сказал, в чём ошибка в алгоритме. А я привел пример, как её исправить.

Походу - не факт. Смоделировал, даже картинки те же взял. Его алгоритм тоже работает. На глаз даже большой разницы нет. Ошибка где-то не здесь. У него где-то "переполнение", судя по изменению цвета на картинках.
Особист, у тебя переменные как объявлены?
Иногда лучше вовремя остановиться...
И начать заново!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Графический эффект перехода одного изображения в другое.

Сообщение alibek » 05.07.2010 (Пн) 22:55

Alec писал(а):Его алгоритм тоже работает.

Его алгоритм не может работать.
Не хватает внешнего цикла, градиента.
Lasciate ogni speranza, voi ch'entrate.

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Графический эффект перехода одного изображения в другое.

Сообщение Alec » 05.07.2010 (Пн) 23:20

alibek писал(а):
Alec писал(а):Его алгоритм тоже работает.

Его алгоритм не может работать.
Не хватает внешнего цикла, градиента.

Э...
Alec писал(а):Сколько раз выполняется приведенный тобой код?

Особист писал(а):Alec, всегда по-разному, т.к. неизвестно сколько раз нужно изменить цвет каждого пикселя, чтобы достигнуть конечного изображения.
Поэтому я предполагал реализовать счётчик или флаг, типа
1 count = 0
... начало цикла обработки
... если случилось изменить цвет пикселя, то count = count + 1
... конец цикла обработки
doevents 'это чтобы было видно результат и не зависало'
if count then goto 1

Но гонял код просто по нажатию кнопки, т.к. уже на 2-3 преобразованиях становилось понятно, что картинка рисуется не так, как задумано.

Дико, страшно - но цикл! (Естественно я моделировал циклом For-Next, но в данном случае суть не в этом)
Иногда лучше вовремя остановиться...
И начать заново!

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 05.07.2010 (Пн) 23:45

Вот проколупавшись пару часов допилил проект.
Во многом благодаря быстрым примерам Alec'а получился более-менее работоспособный образец. Я переписал код с нуля, т.к. предыдущий образец остался на работе. В итоге, избавившись от процедур перевода Dec -> Hex через String, заработало более сносно - возможно, проблема была в них.
Я всё равно не понимаю, почему всё завершается странноватым эффектом "замыливания", чтоли, однако вцелом задачу решает!
Прилагаю результат. Буду признателен, если найдутся желающие решить последнюю головоломку.
ЗЫ iGrok, твой код я конечно попробовал, но получилось ровно то, что изображено на картинке постом ниже. Допускаю, что в этом моя ошибка.

Скачать проект (с возм-тью кэширования полученных кадров, регулировкой скорости и т.д.) можно по ссылке
http://www.pokesoft.narod.ru/rbgchange.zip

Вот отдельно та самая процедура:
Код: Выделить всё
Command4.Enabled = False
pix = 0
st = Val(Combo1)
0 cnt = 0
For f = 0 To 100
    For g = 0 To 100
        l = Picture1.Point(f, g)
        m = pic(1).Point(f, g)
        If l - m = 0 Then GoTo 1
            If Not cnt Then cnt = cnt + 1
           
            R1 = l And &HFF
            G1 = l \ &H100 And &HFF
            B1 = l \ &H10000 And &HFF
            R2 = m And &HFF
            G2 = m \ &H100 And &HFF
            B2 = m \ &H10000 And &HFF
           
            If st = 1 Then GoTo 1
            If Abs(R1 - R2) <= st Then R1 = R2
            If Abs(G1 - G2) <= st Then G1 = G2
            If Abs(B1 - B2) <= st Then B1 = B2
           
1           If R1 > R2 Then R1 = R1 - st
            If G1 > G2 Then G1 = G1 - st
            If B1 > B2 Then B1 = B1 - st
           
            If R1 < R2 Then R1 = R1 + st
            If G1 < G2 Then G1 = G1 + st
            If B1 < B2 Then B1 = B1 + st
           
            l = RGB(R1, G1, B1)
            Picture1.PSet (f, g), l
2    Next g
If f = 100 / Val(Combo2) Then AddPic
Next f
Me.Caption = "Изменений: " + CStr(cnt)
DoEvents
If Command4.Enabled = True Then Exit Sub
If cnt Then GoTo 0


Всем огромное спасибо! Особенно Alec'у, который даже пробовал моделировать этот проект!
ЗЗЫ Alec, я ща не помню как объявлял переменные в прошлом проекте, приду на работу - гляну, напишу.
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Графический эффект перехода одного изображения в другое.

Сообщение Хакер » 06.07.2010 (Вт) 3:55

Скачать проект

Он ужасен и вообще не работает (в конце картинка начинает «плакать» слезами-артефактами).


Вот скажи, в чём сакральный смысл на каждой итерации извлекать компоненты цветов?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Графический эффект перехода одного изображения в другое.

Сообщение alibek » 06.07.2010 (Вт) 8:11

Alec писал(а):Дико, страшно - но цикл!

Да, в исходном примере этого не было, а дальше я не заметил.
Но все-равно этот пример не может давать нормального результата, потому что разные составляющие приводятся не одновременно.
Lasciate ogni speranza, voi ch'entrate.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Графический эффект перехода одного изображения в другое.

Сообщение Хакер » 06.07.2010 (Вт) 8:12

Кстати, начиная с 2000 в линейке NT и 98 в линайке 9x, в Windows есть API-функция AlphaBlend.
Ничего особенного в ней нет, но сделать так же быстро на VB автор замучается судя по его результатам.

Так может быть стоит использовать API, в которую уже всё инкапсулировано?

Пример прилагается:
Вложения
api-blend-sample.rar
(63.06 Кб) Скачиваний: 191
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Особист
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 122
Зарегистрирован: 10.05.2006 (Ср) 12:46

Re: Графический эффект перехода одного изображения в другое.

Сообщение Особист » 06.07.2010 (Вт) 9:31

Хакер, вот именно такой пример и был мне нужен! Большое спасибо!
Из минусов как я понимаю здесь основной, что не будет работать на Windows старше 2k, сомневаюсь что много народа используют нынче 9х.
Поэтому просто огpомное тебе спасибо ещё раз!

По поводу моего примера - да, я кончено же просто любитель, но тем не менее пусть и тормознуто, но работает.
Мне нужно было узнать, в чём ошибка алгоритма. Скорость и красота кода роли на тот момент не играли.
Если бы я записывал полученные кадры в один файл, а потом с помощью своего же контрола их из него показывал - работало бы не менее шустро, и даже на 95 винде.
Про упомянутые тобою "потёки" я писал - если удастся их устранить, то это и докажет возможность моего подхода. Если не удастся - то почему?
RANDOMIZE USR 15619: REM: LOAD "VBSTREETS"

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Графический эффект перехода одного изображения в другое.

Сообщение Хакер » 06.07.2010 (Вт) 9:46

но тем не менее пусть и тормознуто, но работает.

Печально, если ты не понял правильного пути и теперь будешь использовать код из моего примера. Ещё одно потверждение вредности примеров.

Ещё раз повторяю. Внимай, думай.

Для чёрно-белой картинки:
Есть исходная картинка, есть конечная картинка.
Если речь идёт о плавном превращении исходной картинки в конечную, значит речь идёт о показе некоторого числа n-1 промежуточных картинок. Цвет любой точки i-той промежуточной картинки из N-возможных высчитывается так:
Математическая формула: P_i = P_0 \frac{i}{n}+P_n(1-\frac{i}{n})
Где Математическая формула: P_0 — цвет этой точки в начальной картинке, а Математическая формула: P_n — в конечной.

А если картинка не черно-белая, а цветная, нужно разделить цвета на компоненты и каждый компоенент точки промежуточной картинки расчитать по этой формуле. У тебя в коде нет ничего похожего на эту формулу.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 64

    TopList