Конференция "Media" » Как выводить полупрозрачные битмапы? [D7, WinXP]
 
  • AutoBOT (31.05.09 03:26) [0]
    Задался как-то вопросом "Как выводить полупрозрачные битмапы?"...

    Посоветовали функцию "Windows.AlphaBlend;", начал потихоньку разбираться с ней, но получается выводить только на форму... :(

    В Image1, например, не хочет нарисовываться... :(

    Есть ли более нормальный способ, или это я как-то не так делаю?
  • Игорь Шевченко © (31.05.09 15:55) [1]

    > Посоветовали функцию "Windows.AlphaBlend


    правильно посоветовали


    > но получается выводить только на форму


    вообще-то она в любой dc выводит, а не на форму. в том числе и в image.bitmap.canvas.handle
  • AutoBOT (31.05.09 22:25) [2]
    Я пробовал выводить по-всякому...
    В том числе и в "Image1.Picture.Bitmap.Canvas.Handle"...

    Потому и спрашиваю, что ничего не выходит... :(
  • antonn © (01.06.09 14:19) [3]

    > правильно посоветовали

    не стоит.


    > AutoBOT   (31.05.09 03:26)

    глянь это: http://desksoft.ru/index.php?forum=13&th=187
  • Игорь Шевченко © (01.06.09 22:10) [4]

    > глянь это: http://desksoft.ru/index.php?forum=13&th=187


    Красиво. Но те, кто делает формы с position=poDesktopCenter подлежат принудительной эвтаназии, потому что растаскивать из центра двух мониторов - не самое интересное занятие :)
  • AutoBOT (01.06.09 22:44) [5]
    > глянь это: http://desksoft.ru/index.php?forum=13&th=187

    Здорово... Неужели Вы это всё сами придумали?))

    По каким книгам можно выучить такие приёмы?

    А с Windows.AlphaBlend; значит уже ничего нельзя поделать? :(
  • antonn © (02.06.09 00:03) [6]

    > Но те, кто делает формы с position=poDesktopCenter подлежат
    > принудительной эвтаназии, потому что растаскивать из центра
    > двух мониторов - не самое интересное занятие :)

    у меня небыло еще двух мониторов :)
    а что ставить тогда? SystemParametersInfo() вернет так же область с объединенных мониторов? (в куче проектов для центра ее использовал :))


    > AutoBOT   (01.06.09 22:44) [5]

    после прыганий вокруг AlphaBlend и не такое придумаешь :)
    тут просто попиксельное наложение, формулы блендинга общедоступны
  • Игорь Шевченко © (02.06.09 00:12) [7]
    antonn ©   (02.06.09 00:03) [6]

    Я для splash-eй ставлю poScreenCenter, помогает.
  • antonn © (02.06.09 00:58) [8]
    Screen - не на середине экрана рисует сплеш? в смысле не в центре рабочей области
  • Игорь Шевченко © (02.06.09 01:06) [9]
    antonn ©   (02.06.09 00:58) [8]

    Нет, он рисует посередине экрана на том мониторе, откуда запустили :) В смысле, по умолчанию, на PrimaryMonitor. А если передвинул на другой монитор, то по центру экрана другого монитора (D2006 по меньшей мере так себя ведет).

    Кстати, у тебя случаем нету подобного примера с переходом одной картинки в другую (плавным переходом) ? :)
  • antonn © (02.06.09 01:13) [10]
  • Игорь Шевченко © (02.06.09 01:33) [11]

    > такой пойдет? :)


    Спасибо, конечно, но как-то резко, плавнее бы :)
    Наподобие того, как в setup-ах.
    Хочу splash сделать с переходом одной картинки в другую (ну с очень плавным постепенным переходом).

    Блажь конечно, но забавно.
  • antonn © (02.06.09 01:38) [12]
    там просто выбирается каждый десятый кадр из 255 (в процедуре OnDraw_out()), пример просто для другого делался :)
    а так в RedrawPic() передается два битмапа (32 бита) и процентное соотношение блендинга (0-100)
  • antonn © (02.06.09 01:40) [13]
    собсно в thread_splash_scanline.pas процедура CopyBitmapAlfa32to32_gray() делает тоже самое, только учитывая еще альфаканал первого битмапа
  • AutoBOT (02.06.09 01:45) [14]
    Есть процедура перетекания одного изображения в другое:

    http://programmersforum.ru/showpost.php?p=272080&postcount=4
  • Игорь Шевченко © (02.06.09 01:54) [15]
    AutoBOT   (02.06.09 01:45) [14]

    > http://programmersforum.ru/showpost.php?p=272080&postcount=4


    Procedure PicToPic(PicName1,PicName2,Times,Sleeper: String);
    Var
     bm, bm1, bm2: TBitMap;
     p1, p2, p: PByteArray;
     i, y, x: integer;
    Begin
     Sleep(StrToInt(Sleeper));
     bm := TBitMap.Create;
     bm1 := TBitMap.Create;
     bm2 := TBitMap.Create;
     bm1.LoadFromResourceName(HInstance,PicName1);
     bm2.LoadFromResourceName(HInstance,PicName2);
     bm.PixelFormat := pf24bit;
     bm1.PixelFormat := pf24bit;
     bm2.PixelFormat := pf24bit;
     bm.Height :=bm1.Height;
     bm.Width :=bm1.Width;
     FRMIntr.IMGIntroSplash.Canvas.Draw(0, 0, bm1);
     For i := 1 To StrToInt(Times) - 1 Do
     Begin
      For y := 0 To bm.Height - 1 Do
       Begin
         p := bm.ScanLine[y];
         p1 := bm1.ScanLine[y];
         p2 := bm2.ScanLine[y];
         For x := 0 To bm.Width * 3 - 1 Do
           p^[x] := round((p1^[x] * (StrToInt(times) - i) + p2^[x] * i) / StrToInt(times));
       End;
       FRMIntr.IMGIntroSplash.Canvas.Draw(0, 0, bm);
       Application.ProcessMessages;
       Sleep(5)
     End;
     bm1.Destroy;
     bm2.Destroy;
     bm.Destroy;
    End;



    StrToInt(times) - это, надо понимать, чтобы не сильно быстро перетекало ? :)
  • Игорь Шевченко © (02.06.09 01:55) [16]

    > а так в RedrawPic() передается два битмапа (32 бита) и процентное
    > соотношение блендинга (0-100)


    угу, спасибо, поглянем
  • Sapersky (02.06.09 11:46) [17]
    после прыганий вокруг AlphaBlend и не такое придумаешь :)

    Хм, а чем так страшна AlphaBlend?
    Я её толком не использовал, но по тестам - вроде работает, и не слишком медленно (сопоставимо с самописными методами).
    Хотя premulted alpha может ввести новичка в ступор, это да. И непоследовательно как-то со стороны MS - в одном месте избавить от ковыряния в пикселях, в другом - наоборот, заставить...
  • antonn © (02.06.09 12:46) [18]
    На некоторых системах она вообще не работала (на win2k, она не от GDI+ зависит?), пару раз присылали скриншоты, где по краям оставался какой то грязный ореол (вот тот яркорозовый фон который применяют обычно для transparent color с нанесенным изображением).
    А еще она позволит вывести с полупрозрачностью картинку с альфой? :)
    да еще с перерасчетом альфы конечного изображения (вот это меня заставило окончательно от нее отказаться).
  • antonn © (02.06.09 12:50) [19]
    а что мне действительно не понравилось, почему в GDI все 24х битное, т.е. я не могу нарисовать линию цветом с альфой (в четвертом байте), все равно на картинке рисуется линия, а альфа под ней просто затирается, в результате если выводить ее через updatelayeredwindow будет дырка (точнее на светлом фоне будет дырка, а на темном виден цвет на линии). Так же и с текстом, приходится изгаляться с масками всякими.
  • Игорь Шевченко © (02.06.09 13:35) [20]

    > а что мне действительно не понравилось, почему в GDI все
    > 24х битное


    в gdi все зависит от характеристик растра, на котором он рисует. Через 32-х битный битмап, по крайней мере, альфа очень даже учитывается
  • antonn © (02.06.09 14:48) [21]
    я создаю tbitmap с pf32bit, рисую на нем цветом:
    function Get_color_transparent(col:tcolor; trans:byte):integer;
    begin
    result:=col or (trans shl 24);
    end;

    var col:integer;
    begin
    col:=Get_color_transparent(clred,128);


    получаю обнуленную альфу :(
  • Sapersky (02.06.09 20:30) [22]
    На некоторых системах она вообще не работала (на win2k, она не от GDI+ зависит?)

    У меня как раз на win2k работает. Хотя я только на одной машине тестировал.
    От GDI+ AlphaBlend не должна зависеть, она в msimg32.dll находится, которая есть даже в win98. Но в 98 она работает только при выводе на экран, в битмап - сразу AV; впрочем, официально 98 вообще не поддерживается ( http://msdn.microsoft.com/en-us/library/dd183351(VS.85,printer).aspx ).

    Вообще непонятно, что там может глючить. Пытается аппаратно ускорять и не получается из-за кривых драйверов? Но ты же использовал, наверное, вариант битмап->битмап с pf32bit, а там никакого ускорения не может быть в принципе.
    Попытался поискать (хотя и не очень старательно) - нашёл только это:
    http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100477
    Там с выводом на экран, довольно специфичный случай.

    А еще она позволит вывести с полупрозрачностью картинку с альфой? :)

    Одновременно с попиксельной и общей альфой - да, хотя и несколько медленнее (что в общем понятно). "The SourceConstantAlpha value is combined with any per-pixel alpha values" (MSDN).

    да еще с перерасчетом альфы конечного изображения (вот это меня заставило окончательно от нее отказаться).

    Судя по формулам отсюда:
    http://msdn.microsoft.com/en-us/library/dd183393(VS.85,printer).aspx
    Dst.alpha она должна считать - возможно, не так, как тебе нужно, но не затирать 0-м во всяком случае.

    Вообще я не спорю с тем, что самописные функции удобнее, гибче, в некоторых случаях - быстрее, и т.д. Просто подумал, что автору вопроса для начала подошла бы и стандартная.
  • Sapersky (02.06.09 20:49) [23]
    Тест (пример использования) AlphaBlend, если кому надо:
    http://sapersky.narod.ru/files/AlphaBlend_VCL_test.rar
  • AutoBOT (02.06.09 23:54) [24]
    Спасибо всем...) ^_^



    А как насчёт "Windows Vista / 7" и их знаменитого "Aero" ?

    Я слышал, мол, в XP весь интерфейс построен на AlphaBlend, а в "Windows Vista / 7" MicroSoft просто доработало старую функцию AlphaBlend добавив новых функций, оптимизировав и ускорив её...

    Это так? А можно ли пользоваться этой обновлённой AlphaBlend в XP ?



    Более удобные и производительные способы - это, конечно, превосходно и я буду разбираться со способом antonn'а...
    Но ведь и "классику" надо знать... ;)
  • Sapersky (03.06.09 12:28) [25]
    Я слышал, мол, в XP весь интерфейс построен на AlphaBlend, а в "Windows Vista / 7" MicroSoft просто доработало старую функцию AlphaBlend добавив новых функций, оптимизировав и ускорив её..

    А я слышал, что рендер Висты построен на аппаратном ускорении. Ну и просто по логике - иначе зачем Aero требует видеокарту с шейдерами? (хотя логика у MS зачастую странная...)
    Если бы были какие-то обновления в AlphaBlend - в MSDN было бы об этом написано, а там (см. ссылки из [22]) ничего нет.
    MS, кажется, сейчас больше склонен придумывать новые API, чем развивать старые - для Висты вот придумали Direct2D. Как бы из объективных соображений, но и не без субъективного желания перетащить на новую ОС. Точнее даже не для Висты, а для 7-ки, поддержку Висты ещё только обещают.
    В общем, у MS либо малофункциональная "классика", либо сверхсовременный в первую очередь по системным требованиям "модерн". Ну ещё GDI+ есть как некий промежуточный вариант, но его часто ругают за тормознутость.
    И чем пытаться выбрать из ассортимента MS меньшее из зол - возможно, лучше изучать основы, либо обработку изображений на софтвере, по примерам Антона или на какой-нибудь другой open-source граф. библиотеке, либо аппаратную графику на базовом API - OGL, D3D.
  • Pavia © (03.06.09 23:35) [26]

    > А я слышал, что рендер Висты построен на аппаратном ускорении.

    Я это и про 98 слышил.


    > (вот тот яркорозовый фон который применяют обычно для transparent
    > color с нанесенным изображением).

    Я такое и в DX7 наблюдал. На всех картачках норм на одной розовый фон.

    Выход один делать все что в наших силах.
  • Sapersky (04.06.09 10:22) [27]
    Судя по информации отсюда:
    http://en.wikipedia.org/wiki/Desktop_Window_Manager
    GDI (рисование клиентской области окон) не ускоряется, более того, отрезали даже те зачатки ускорения, которые у него были (впрочем, настолько кривые, что мне их не жалко). Ускоряется рисование заблюренных рамочек, тумбнэйлов окон, смешивание полупрозрачных окон, сворачивание-разворачивание в 3D и т.п. Хотя почти всё из этого набора, ИМХО, можно сделать и на софтвере, разве что достаточно быстрое 3D-разворачивание получить тяжко.
    В общем, с классическими GDI-приложениями получается "полуаппаратная" графика. Полностью аппаратная - только при выводе UI новыми средствами вроде WPF (вероятно, там переписали рисование контролов на D3D). Впрочем, в случае WPF тормоза .NET, наверное, успешно компенсируют всякое ускорение.
    В других источниках пишут примерно то же самое:
    http://blogs.msdn.com/greg_schechter/archive/2006/03/05/544314.aspx
    http://blogs.msdn.com/greg_schechter/archive/2006/03/10/549310.aspx
  • AutoBOT (05.06.09 01:42) [28]
    Что ж делать? :(
  • Sapersky (05.06.09 14:14) [29]
    А что нужно-то? Спецэффекты в стиле Vista Aero? Так я уже писал: "почти всё из этого набора, ИМХО, можно сделать и на софтвере" ну и далее см. "лучше изучать основы, либо обработку изображений на софтвере, по примерам Антона или на какой-нибудь другой open-source граф. библиотеке".
    Какие-нибудь другие - это, например, FastLIB, Graphics32, SpriteUtils-2, DelphiX/TDIB и т.д.
    По поводу FastLIB vs TBitmap я уже высказывался здесь ([99]):
    http://pda.delphimaster.net/?id=1186325580&n=9&p=5
    По теории обработки изображений есть неплохой сайт (на английском):
    http://homepages.inf.ed.ac.uk/rbf/HIPR2/index.htm
  • AutoBOT (05.06.09 22:53) [30]
    Вот как раз с английским и плоховато...
    Особенно с техническим...((

    Мануалы-то смотрел, но по английски не понятно ничего...(

    "рендер Висты построен на аппаратном ускорении" - а как это на деле? Самому можно тоже как-то так делать?



    Кстати, а кто из "кто-нибудь других" Вам больше нравится и почему (из-за каких достоинтств) ? :)
  • Sapersky (06.06.09 10:39) [31]
    "рендер Висты построен на аппаратном ускорении" - а как это на деле? Самому можно тоже как-то так делать?

    Если коротко - каждое окно рисует себя не прямо на экран, а во внутренний буфер (битмап), затем эти битмапы отдаются Desktop Window Manager, который перегоняет их в D3D-текстуры и рисует окна как полигоны с наложением этих текстур, с любыми доступными через 3D эффектами.
    Как рисовать полигоны - см. Краснова:
    http://d3dengine.narod.ru/books.html
    Или исходники 2D-игрушек c igdc.ru.
    Единственный относительно сложный эффект, для которого требуются шейдеры - пресловутые заблюренные рамочки (если, конечно, список спецэффектов Aero исчерпывается тем, что я перечислил в [27] - я с Вистой "вживую" работал всего минут 15, чего-то мог и не заметить).
    По шейдерам при желании тоже можно найти материалы:
    http://forum.vingrad.ru/forum/topic-73464.html
    Ну и примеры к DX9 SDK с clootie.ru.

    Кстати, а кто из "кто-нибудь других" Вам больше нравится и почему (из-за каких достоинтств) ? :)

    Ещё раз для тех кто в танке:
    http://pda.delphimaster.net/?id=1186325580&n=9&p=5
    99-й пост, в самом конце страницы.
    К достоинствам могу добавить компактность, нет привязки к сторонним модулям (даже из стандартных используется только windows.pas).
    Есть у FastLIB и свои недостатки - кривость с т.з. ООП, неустойчивость к ошибкам, отсутствие документации и некоторых важных функций (того же попиксельного альфа-блендинга в стандартном комплекте нет, хотя для себя я давно написал/утащил из SpriteUtils).
    Graphics32 примечательна главным образом тем, что есть готовые компоненты для отображения картинки (аналог TImage), встроенная работа со слоями, элементы векторной графики.
    SpriteUtils шустра, но неудобна в использовании, заточена главным образом под KOL, исходники плохо читаются из-за чрезмерного пристрастия автора к ассемблеру. Хотя можно использовать как практическое пособие по asm.
  • Sapersky (08.06.09 18:56) [32]
    Набросал пример полупрозрачности с блюром (те самые рамочки окон) на TBitmap.
    http://sapersky.narod.ru/files/Vista_style_effects.rar
    Блюр относительно медленный, т.к. используется простой и тупой алгоритм. Можно быстрее, здесь я писал по поводу оптимизации Mean-фильтра:
    http://pda.delphimaster.net/?id=1241286940&n=7
  • имя (06.07.09 04:55) [33]
    Удалено модератором
  • имя (28.07.09 20:28) [34]
    Удалено модератором
  • Eraser © (30.07.09 03:48) [35]
    > [17] Sapersky   (02.06.09 11:46)


    > Хм, а чем так страшна AlphaBlend?

    вот тоже не понятно, по-моему отлично работает. в крайнем случае можно результирующий битмап 24 битным сделать.
  • antonn © (30.07.09 22:39) [36]

    > Eraser ©   (30.07.09 03:48) [35]
    >
    > > [17] Sapersky   (02.06.09 11:46)
    >
    >
    > > Хм, а чем так страшна AlphaBlend?
    >
    > вот тоже не понятно,

    [18] :)
  • CSS (02.08.09 05:20) [37]
    Sapersky, но это же внутри TImage... А как рисовать так саму форму? =))
  • Sapersky (03.08.09 14:40) [38]
    В моих примерах TImage используется только для хранения картинки. С тем же успехом можно грузить и из файлов, просто мне лень было вспоминать, как загрузить jpeg используя стандартный модуль.
    А рисуется всё либо на форму (в первом примере есть переключатель to bitmap/to screen), либо в буферный битмап по размеру формы (точнее, PaintBox'а, который задаёт область рисования) и потом этот битмап выводится на PaintBox.
    И кстати, у меня с использованием буфера рисуется быстрее, особенно заметно при использовании общей прозрачности, разница более чем в 10 раз.
  • UnodoFot (04.08.09 14:56) [39]
    Соглашусь с автором. Многое из вышеперечисленного действительно актуально
  • antonn © (04.08.09 15:05) [40]

    > Sapersky   (03.08.09 14:40) [38]

    он скорее спрашивает как сделать форму такой, как у тебя в примере :)
    т.е. вместо картинки беграунда должно быть то, что под формой, что, имхо, нереально на всяких ХП.
  • CSS (04.08.09 17:29) [41]
    Точно... =)

    Но у моего знакомого же как-то получилось... =(

    Правда немного дёргается при перетаскивании, а так почти как надо...
  • antonn © (04.08.09 20:36) [42]
    можно фотографировать фон под формой и его выводить заблюренным - но ормозить это будет невероятно, и лагать
  • CSS (04.08.09 21:59) [43]
    А как фотографировать фон под формой?
    Знакомый мне не говорит как он делал... =(

    А "заблюренным" - это как бы через матовое стекло чтоль? =)
    Только зачем так? У него была просто "стелянная" форма...
    И не тормозила... Только подёргивалась чуть... =))
  • Б (05.08.09 10:30) [44]
    Form1.AlphaBlend
    Form1.AlphaBlendValue
  • antonn © (05.08.09 13:14) [45]
    стекло можно сделать как в [3], только с контролами напряг
  • CSS (05.08.09 17:44) [46]

    > Б   (05.08.09 10:30) [44]


    Да нет же... Этот Form1.AlphaBlend только делает полупрозрачным всё подряд...
    А он как-то сделал часть формы "стеклянной" (похожей на дыру посреди формы)...
    Говорил случайно получилось...
    А потом превратил её в матовое стекло...

    Кстати, а что может означать ошибка "Canvas does not allow drawing." ?
  • Б (06.08.09 22:00) [47]

    > CSS   (05.08.09 17:44) [46]


    Да он и впрямь - колдун!
    P. S. А что с регионами работать не умеем?
  • CSS (06.08.09 22:08) [48]
    > Да он и впрямь - колдун!
    > P. S. А что с регионами работать не умеем?


    Не... Он просто афигенно везучий...
    Один раз 5000-ную купюру на улице нашёл... И дважды 1000-ю... х_Х

    Сорри за флуд... =(



    Про "Canvas does not allow drawing." спрашиваю потому что та самая прога с этой ошибкой вылетает минут через пять...
    И вырубается тогда только через процессы...

    А причём тут регионы-то?
    Ну рамку он скруглял скорее всего регионами, но и только...
    Как они могут относиться к выводу полупрозрачных битмапов? о_О
  • Б (07.08.09 11:03) [49]
    Короче, ищи компонент - Glassy.
  • CSS (07.08.09 23:06) [50]
    Посмотрел, компонент забавный, спасибо... =)

    Но у того знакомого и в помине нету никаких нестандартных компонентов...
    И изображение подёргивается сильнее чем в Glassy... =(
  • Б (07.08.09 23:38) [51]

    > И изображение подёргивается сильнее чем в Glassy... =(


    И чё? Тебе от этого хуже?
    Бери готовый компонент и радуйся.
    И чё за знакомый такой , что код не показывает или ты даже и не спрашивал? Даже напраления рыть?
    Думаю вопрос исчерпан.
  • CSS (08.08.09 01:40) [52]
    Да я кое-какую прогу не успевал доделать вовремя...
    Совсем прижало, вот я и стырил кусок кода из его наработок не спросив... =(
    Теперь он вообще ничего мне не показывает... =((
    Сказал только "Использовал форму, таймер и кнопку"...

    Просто интересно очень как он такое сотворил...



    А по теме только один вопрос остался: Объясните пожалуйста, что делает процедура PremultAlpha из проекта AlphaBlend_VCL_test с полупрозрачностью?
  • antonn © (08.08.09 14:05) [53]
    она затемняет каналы RGB, чем меньше альфа, тем сильнее.
    я хз как их рисует винда, но при выводе через UpdatelayeredWindow() белая область картинки с нулевой альфой будет видна как белая муть прозрачная для кликов мышкой. И без такой процедуры уже не обойтись.
    Хотя, если прикинуть, это неправильно - ведь тогда края картинки "зачерняются".
  • CSS (08.08.09 23:15) [54]
    > белая область картинки с нулевой альфой будет видна как
    > белая муть прозрачная для кликов мышкой.


    Мышкой не проверял, но у меня примерно так и получалось без этой процедуры...
    Сначало было ощущение, что Windows.AlphaBlend рисует как бы инвертированно что ли.....
    Потом подумалось что если Alpha=255 то она накладывает с Alpha=255, а если Alpha=0 - с Alpha=180... Как бы диапазон не так воспринимает...

    А возможно самому накладывать полупрозрачную картинку, смешивая цвета (основываясь на величину Alpha данного пикселя)?
    Есть у кого-нибудь формулы, зависимости или что-то такое? =)
  • Sapersky (09.08.09 18:04) [55]
    Обычная формула блендинга:
    DstColor = SrcColor * SrcAlpha + DstColor * (1 - SrcAlpha)
    Есть во 2-м примере, там сначала блюр, потом блендинг.
    AlphaBlend использует такую:
    DstColor = SrcColor + DstColor * (1 - SrcAlpha)
    (что, кстати, расписано по ссылке http://msdn.microsoft.com/en-us/library/dd183393(VS.85,printer).aspx , которая приводилась ещё в [22])
    С т.з. быстродействия должно быть немного лучше, т.к. экономится одно умножение. Но практически, насколько помню, полная формула через MMX всё равно быстрее.
    Соответственно PremultAlpha выполняет операцию:
    SrcColor = SrcColor * SrcAlpha
    Ну и на практике к формулам добавляется сдвиг вправо (shr 8, 16) - эквивалент div 256, 65536 - чтобы привести результат к диапазону 0..255.
  • CSS (16.08.09 03:46) [56]
    > Sapersky   (09.08.09 18:04) [55]

    Ой... Проглядел... =((

    Спасибо... =))
  • Вася (26.01.10 11:52) [57]
    > Кстати, а что может означать ошибка "Canvas does not allow drawing." ?

    она может быть из-за неправильного использования Canvas.Lock и Canvas.Unlock,а может и из-за утечки памяти(какие-нибудь GetDC в цикле делаете,а ReleaseDC забыли)

    > DstColor = SrcColor * SrcAlpha + DstColor * (1 - SrcAlpha)
    > DstColor = SrcColor + DstColor * (1 - SrcAlpha)


    эм...кажется так должно быть: round(SrcColor + DestColor * (1 - SrcAlpha / 255))

    Но практически, насколько помню, полная формула через MMX всё равно быстрее.



    а кто такой MMX?можно где-то посмотреть эту полную формулу?=)
  • antonn © (26.01.10 13:55) [58]
    полная формула выше, домножаешь исходник на альфу, спрайт на обратную альфу и складываешь (или наоборот, не помню).
    ммх - это расширение, восемь регистров в 64 бита =)
  • Вася (26.01.10 14:09) [59]
    да я про эту фразу:

    > Но практически, насколько помню, полная формула через MMX всё равно быстрее.

    где посмотреть на эту ускоренную формулу?

    > ммх - это расширение, восемь регистров в 64 бита =)

    не понял...можно попроще?=(
  • antonn © (26.01.10 15:40) [60]
    ММХ - реализация, а не формула. Это ассемблер, к общим регистрам можно использовать дополнительно 8 регистров заимствуюя их у FPU, со своими командами и отлично подходящие для потоковой обработки.

    http://pda.delphimaster.net/?id=1192295230&n=7
    http://pda.delphimaster.net/?id=1258745999&n=7
  • Вася (27.01.10 19:17) [61]
    ссылки почитал,спасибо...вот только сложновато(точнее ничё не понятно).=(в делфи надо что-то доустанавливать?
    может есть примеры попроще?попробую тогда написать блендинг.^_^
    а то даже чтот не пойму никак как в него вообще переменные запихивать.....%(

    в одной статье написано что он не заимствует регистры у FPU, а нужно просто чтоб там было одно и тоже - для сохранения мультизадачности...%)

    и что выяснить есть ли в системе mmx не совсем просто - то есть его может и не быть на компе?
    вот эверест сказал про процессор:

    > "Наборы инструкций - x86, x86-64, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1"

    значит у меня оно есть?))
    а SSE тоже что-то тоже такое же?кто лучше?=)
  • antonn © (28.01.10 09:24) [62]

    > и что выяснить есть ли в системе mmx не совсем просто -
    > то есть его может и не быть на компе?

    да, может не быть, например на P1-133 его нету :)
    на P2 он уже есть, чтобы определить поддержку надо вытащить CPUID, и это делается по первой ссылке у > homm ©   (14.10.07 14:44) [12].
    CPUID, кстати, тоже может не быть, на еще более древних процессорах :)


    > а SSE тоже что-то тоже такое же?кто лучше?=)

    смотря как применять...
  • Вася (29.01.10 10:03) [63]
    с горем пополам сделал по тем примерам из ссылок такое:

    procedure TForm1.Button2Click(Sender: TObject);
    const mask: int64=$FFFFFFFFFFFFFFFF;
    var pt: Pointer; c: Integer;
    begin
    c:=Image1.Picture.Bitmap.Width*Image1.Picture.Bitmap.Height*3 div 8; // подобрал чтоб для pf24bit работало не вылетая
    pt:=Image1.Picture.Bitmap.ScanLine[Image1.Picture.Bitmap.Height-1]; // тут ведь указатель нужен?
    asm
    mov ecx, c
    mov esi, [pt]
    movq xmm1, mask
    @@Cycle_1:
     movq xmm0, [esi]
     pmullw xmm0, xmm1
     movq [esi], xmm0
     add esi, 8
     loop @@Cycle_1
    emms
    end;
    Image1.Repaint;
    end;



    не очень понимаю что именно и как оно делает, но внешне смахивает на негатив...

    может есть у кого примеры попонятнее?а то полунаугад не очень результативно выходит...=(
  • Вася (30.01.10 18:05) [64]
    не знаю что делалось через pmullw,но теперь мне удалось сделать нормальный негатив(правда скорость кажется пострадала):

    procedure TForm1.Button3Click(Sender: TObject);
    const mask: int64=$FFFFFFFFFFFFFFFF;
    var pt: Pointer; c: Integer;
    begin
    c:=Image1.Picture.Bitmap.Width*Image1.Picture.Bitmap.Height*3 div 8; // pf24bit
    pt:=Image1.Picture.Bitmap.ScanLine[Image1.Picture.Bitmap.Height-1];
    asm
    mov ecx, c
    mov esi, [pt]
    @@Cycle_1:
     movq xmm0, [esi]
     movq xmm1, mask
     psubb xmm1, xmm0
     movq [esi], xmm1
     add esi, 8
     loop @@Cycle_1
    emms
    end;
    Image1.Repaint;
    end;



    я так понял что с MMX циклы только на ассемблере через "loop <метка>" можно делать?а то через "for i:=0 to ..." сразу вылетает нафиг...
    и почему там xmm0 а не mmx0?

    вобщем скоро думаю получится реализовать быстрый блендинг...=)


    > эм...кажется так должно быть: round(SrcColor + DestColor * (1 - SrcAlpha / 255))

    так я прав что делить тут надо?что-то совсем в формулах на msdn запутался...что их там так много разных про одно бленд-смешивание?
  • antonn © (30.01.10 22:54) [65]
    xmm - это регистры SSE, mmx - это уже то самое :)

    я выше дал ссылки, там в самих темах можно почерпнуть что нужно, либо там же по ссылкам
  • Вася (31.01.10 21:31) [66]
    а...я пробовал писать наоборот mmx0,но говорилось неизвестный инентификатор.
    получается чтоб в MMX было надо mm0 писать?хм...а где я тогда xmm0 взял?о_О

    а в чём тогда разница между SSE и MMX если одно и то же получилося?

    подскажите хоть наиболее правильный способ скорость выполнения мерить,а то найденные на форумах чтот разные результаты выдают...
  • antonn © (01.02.10 01:42) [67]
    правильно mm0-mm7, это я так неудачно на автоматизме написал :)


    > а в чём тогда разница между SSE и MMX если одно и то же
    > получилося?

    разные инструкции, в SSE (бОльших версий) их больше, базовые почти совпадают (возможно и не "почти", особо не разбирался). К тому же ММХ использует регистры FPU, а значит нельзя одновременно пользоваться fpu и ммх. Почти везде где я тупо заменял mm0 на xmm0 все работало, но скорость была ниже на 5-10%.

    Относительную скорость выполнения м/у разными алгоритмами я измеряю с помощью QueryPerformanceCounter().
  • Вася (02.02.10 14:53) [68]
    > Почти везде где я тупо заменял mm0 на xmm0 все работало,
    >  но скорость была ниже на 5-10%.


    нашел в интернете что в MMX "1 операция за такт", а в SSE "1 операция за 2 такта".мож поэтому?
  • antonn © (02.02.10 22:00) [69]
    честно - не знаю, не разбирался. Но мне бы SSE пригодился если бы я наконец разобрался как выровнять данные по 16 байт, чтобы использоваться movaps. Но все никак руки не дойдут :)
  • Вася (04.02.10 09:35) [70]
    что-то не совсем пойму как картинка в памяти хранится.поисковики настойчиво к спецификациям bmp файлов отсылают,но судя по тестам в памяти битмап вовсе не так же хранится...

    а вообще в памяти может не bmp храниться?всмысле если нужно вывести на экран png jpg или там tiff какой-нибудь - всё равно надо будет в bmp конвертировать?
    во всяком случае все api функции вроде только с hbitmap работают...
  • antonn © (04.02.10 12:55) [71]
    png - это, грубо, bmp заархивированный :)
    все переводится в него, 31 байт заголовок, дальше строки в обратном порядке, пиксели в строке в обычном порядке. Мне эта чехарда немного не понравилась и я bmp перегоняю в обычный одномерный массив с "нормальным" порядком строк в один и тот же формат - 32 бита на пиксель (argb). Тогда все операции будут сводиться к указанию первого элемента массива, а дальше к увеличению указателя. Вот тут я рассказывал про такой велосипед: http://forum.vingrad.ru/index.php?showtopic=241113&view=findpost&p=1735682
  • Вася (04.03.10 13:02) [72]
    а как выравнивается?что-то не всегда нормально совпадает...так же как в bmp-файле - по 4?

    > Мне эта чехарда немного не понравилась и я bmp перегоняю в обычный одномерный массив с "нормальным" порядком строк
    > в один и тот же формат - 32 бита на пиксель (argb).


    а так рационально?потом же обратно придётся переводить,время потратится...
  • Sapersky (04.03.10 13:38) [73]
    Если задать битмапу отрицательную высоту, строки будут в нормальном порядке (фирменный стиль MS - интуитивно ни за что не догадаешься).
    Хотя на практике это не использовал - c FastLIB перевёрнутость не так мешает, там и данные, и сканлайны одинаково перевёрнуты (TBitmap пытается умничать и разворачивает сканлайны). Если и требуется какие-то координаты переворачивать, то только один раз, при выводе на экран.
  • antonn © (04.03.10 16:31) [74]

    > а так рационально?потом же обратно придётся переводить,время
    > потратится...

    я по возможности все переворачиваю только один раз, нет привычки при каждом рисовании дергать файл, грузить его и конвертировать.
    К тому же я применяю это только тогда, когда есть смысл, если у меня для поворота картинки "сканлайном" затратится 3,8 секунды, а поворот "массивом" 0,038 то я ее буду грузить даже перед каждым поворотом из битмапа - скорость все равно будет гораздо выше даже с кучей "support"-функций (загрузка выгрузка в битмап и тп).
  • имя (03.05.10 20:18) [75]
    Удалено модератором
  • имя (13.10.11 12:24) [76]
    Удалено модератором
 
Конференция "Media" » Как выводить полупрозрачные битмапы? [D7, WinXP]
Есть новые Нет новых   [118580   +29][b:0.001][p:0.003]