![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 43 Pomógł: 0 Dołączył: 17.07.2008 Ostrzeżenie: (0%) ![]() ![]() |
Witam, jak w temacie, chodzi mi o stworzenie skryptu dzieki ktoremu uzyskal bym przejscie między dwoma zdjęciami przy użyciu gd...
macie jakies pomysły ? jedyne co przychodzi mi do glowy to stopniowe nakladanie transparentu z jednej strony zdjecia do polowy, i tak przygotowane zdjecie nalozyc na kolejne. Kwestia jak to zrobic ? |
|
|
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
GD niestety nie ma nic do zaoferowania sensownego by zrobić takie przejście płynne i, co tu dużo mówić ładnie oraz naturalnie wyglądające, trzeba się posiłkować niestety dość wolno działającymi skryptami, a do tego mało wydajnymi, bo liczenie jest dla każdego piksela obrazu. Sam kiedyś podobny filtr pisałem ale w Matlabie. To przypomina symulację nadawania przezroczystości dynamicznie. Jak działał?
1. Brałem dwa obrazy A i B o tej samej rozdzielczości (jeśli nie były - przeskalowywałem do identycznej) 2. W pętli po całej szerokości robiłem wzorek mniej więcej taki
Możesz owszem kombinować z nadawaniem obu obrazkom tylko poziomu alfa w pętli, ale kod nie różni się wiele od tego powyżej. Różnica leży bowiem tylko w tym jak piksele obrazu traktujesz. A efekt wcale lepszy nie jest. Tylko zwracaj uwagę na szerokość i wysokość, bo we wszystkich 3 muszą być identyczne. Jeśli nie będą, to musisz sam sobie przeskalować A, B i wynik by były! Wydajne to nie jest, ale niestety GD nie ma wsparcia dla nadawania w prosty sposób alfy konkretnemu pikselowi lub grupie pikseli i trzeba to samemu implementować poprzez manipulacją alfy dla każdego piksela z osobna lub poprzez cudowanie. Możesz ewentualnie jeden z obrazów użyć od razu jako wynikowy i to będzie jedyna optymalizacja w sumie. PS... Musisz uważać na zaokrąglenia dla wartości skrajnych. Jeśli trzeba będzie to daj zaokrąglenie w dół bo jest pewniejsze w tym wypadku. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 43 Pomógł: 0 Dołączył: 17.07.2008 Ostrzeżenie: (0%) ![]() ![]() |
Wielkie dzieki thek! chociaz akurat ta wypowiedzia bardzo mnie zniecheciles do GD
![]() exec('fota1.gif -extent 500x100 fota2.gif \ maska.png -gravity East -composite wynik.jpg',$out,$err); Tak przynajmniej opisuja to w manualu, niestety wynik tej funkcji to fota2.gif z nalozona czarna maska, i na to wklejona bez maski fota1.gif Ma ktos doswiadczenie z IM i wie co tu nie gra ? |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 117 Pomógł: 23 Dołączył: 5.03.2011 Ostrzeżenie: (0%) ![]() ![]() |
Cytat trzeba się posiłkować niestety dość wolno działającymi skryptami, a do tego mało wydajnymi, bo liczenie jest dla każdego piksela obrazu Gdyby GD miała jakąś funkcję wbudowaną do tego, to ta funkcja nie liczyłaby dla każdego piksela? :/ |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 43 Pomógł: 0 Dołączył: 17.07.2008 Ostrzeżenie: (0%) ![]() ![]() |
Przetestowalem pare gotowcow ze strony http://www.imagemagick.org/Usage/photos/ i musze stwierdzic ze 2/3 przykladow wogole nie dziala, nie wiedziec czemu "/
|
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Gdyby GD miało wsparcie, to pewnie z racji na zastosowanie doszły by funkcje nadające kolor alfa dla: piksela, wiersza, kolumny obrazu. Bo to co robię tutaj, to efekt podobny do zmiany przezroczystości obrazów kolumnami (od lewej do prawej). Jeśli zamieniłbym od 4 linijki słowa $wysokosc i szerokosc to byłoby to analogiczne do przenikania się obrazów wierszami (od góry do dołu). I gdyby było wsparcie dla nadawania takiego, to bym tykał tylko kanał alfa, a nie grzebał się z choćby imagecolorallocatealpha dla każdego z obrazków, których złożenie potem było by równie problematyczne.
-------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 117 Pomógł: 23 Dołączył: 5.03.2011 Ostrzeżenie: (0%) ![]() ![]() |
Ok, w php "tykałbyś" kanał alfa kolumnami, ale i tak funkcja "tykająca" musiałaby "tyknąć" każdy jeden piksel wybranej kolumny osobno.
Ktoś wie jak to się ma do wydajności? |
|
|
![]()
Post
#8
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
To co Ty chcesz osiągnąć w GD wiązało by się z:
1. Ustawieniem imagealphablending na true 2. Wybrania source image 3. Takiego zmodyfikowania obrazka dołączanego, aby jego parametry alpha każdego piksela tworzyły maskę. 4. Połączenia obrazków. Tak czy inaczej nie obejdzie się bez pętli po całym obrazku dołączanym, który "wprowadzi" odpowiednią maskę do pikseli rozkładając odpowiednio poziomy przezroczystości między 0 (pokrywający) a 127 (całkowicie przezroczysty). Obliczenia ciut mniej wymagające ($i*127/$szerokosc), ale wydajność sobie przetestuj sam, bo dojdzie jeszcze dość kosztowne złożenie obrazków na końcu. Ogólnie da się, ale są to już przetwarzania obrazów dość pamięciożerne, więc nie licz na super wydajność niezależnie czy GD czy Imagemagick. IM ma przewagę, bo jest wykonywany w powłoce, co dość dużo mu daje na plus w tym wypadku. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 117 Pomógł: 23 Dołączył: 5.03.2011 Ostrzeżenie: (0%) ![]() ![]() |
Kazaan, napisz dokładniej jak to ma wyglądać. Może np. obrazki mają po 300px szerokości a nachodzą na siebie tylko na szerokości 100px, tak że tworzą razem 500px?
Sposób podany przez użytkownika thek można zmodyfikować w taki sposób, że $stopienA i $stopienB nie są liniowo a np wykładniczo zależne od szerokości - wtedy dla wąskich kolumn przejścia między obrazkami można osiągnąć lepszy efekt. Ten post edytował aeaeae 7.03.2011, 15:32:24 |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 43 Pomógł: 0 Dołączył: 17.07.2008 Ostrzeżenie: (0%) ![]() ![]() |
Kazaan, napisz dokładniej jak to ma wyglądać. Może np. obrazki mają po 300px szerokości a nachodzą na siebie tylko na szerokości 100px, tak że tworzą razem 500px? Sposób podany przez użytkownika thek można zmodyfikować w taki sposób, że $stopienA i $stopienB nie są liniowo a np wykładniczo zależne od szerokości - wtedy dla wąskich kolumn przejścia między obrazkami można osiągnąć lepszy efekt. Dokladnie tak jak napisales, przykladowo mam 2 obrazki kazdy po 500px i grafika wyjsciowa ma miec 900px... |
|
|
![]()
Post
#11
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
W takim razie więc:
1. Stwórz obraz o ostatecznej wielkości. 2. Skopiuj na niego obrazek A 3. Ustaw alpha blending na true 4. Dla obrazka B znajdź część wspólną obrazka A i B (100px) oraz w skrypcie ustaw odpowiednio wartości dla alpha przeliczając sobie. 5. Skopiuj na wynikowy obrazek ten fragment. 6. Wyłącz alpha blending 7. Skopiuj pozostałą część obrazka B na wynikowy. 8. Zapisz plik. 9. Jeśli nie zadziała to sprawdź czy aby kanałem alpha nie trzeba się zabawić poprzez imagesavealpha. Tak minimalizujesz obniżenie wydajności poprzez operację tylko dla części wspólnej obu. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 43 Pomógł: 0 Dołączył: 17.07.2008 Ostrzeżenie: (0%) ![]() ![]() |
W takim razie więc: 1. Stwórz obraz o ostatecznej wielkości. 2. Skopiuj na niego obrazek A 3. Ustaw alpha blending na true 4. Dla obrazka B znajdź część wspólną obrazka A i B (100px) oraz w skrypcie ustaw odpowiednio wartości dla alpha przeliczając sobie. 5. Skopiuj na wynikowy obrazek ten fragment. 6. Wyłącz alpha blending 7. Skopiuj pozostałą część obrazka B na wynikowy. 8. Zapisz plik. 9. Jeśli nie zadziała to sprawdź czy aby kanałem alpha nie trzeba się zabawić poprzez imagesavealpha. Tak minimalizujesz obniżenie wydajności poprzez operację tylko dla części wspólnej obu. Jak napisaleś tak 'prawie' zarobilem ![]() Po pierwsze robie to w 2 krokach: 1. Na pierwszy obrazek nakładam maskę z gradientem biało -> czarnym - i na podstawie maski wyliczany jest narastajacy transparent 2. Na drugi obrazek nakladam odwrotną maskę. 3. Składam dwa odpowiednio przygotowane obrazki w jeden, z tym że mam jedna uwage, alpha blending musi byc ustawiona na false. przykładowy kod (nie mój) nakładajacy maske na obrazek:
Z nakładanie fotek chyba sobie poradzicie. A tu mam pytanie do znawców imagemagick: jest to kod ktory powinien robic dokladnie to co bylo opisane wyzej, z ta roznica ze w 2 linijkach. Kod jest skopiowany z manuala, zmienilem tylko nazwy plikow, pytanie brzmi: dlaczego to nie dziala?
Duże podziękowania dla thek! ![]() |
|
|
![]()
Post
#13
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Z alphablendingiem trzeba uważać jak sam zauważyłeś. Zwróć uwagę, że ja raz go włączam, a raz wyłączam bo to zależy od tego co robię. U Ciebie w kodzie zwróć uwagę na funkcję imagesavealpha, która załatwia problem przezroczystości. Ogólnie jeśli coś Ci nie wychodzi z przezroczystością to jest to niemal zawsze wina albo imagesavealpha albo alphablendingu źle ustawionych i trzeba to sobie samemu dopasować.
To co napisałeś o wyłączeniu alphablendingu wynika z dokumentacji imagesavealpha -> You have to unset alphablending (imagealphablending($im, false)), to use it. Ot cała tajemnica. Ja kombinowałem bez funkcji imagesavealpha i musiałem w odpowiednich miejscach włączać i wyłączać alphablending. Stąd ciut inaczej to wyglądało, ale efekt powinien być identyczny. Najważniejsze, że osiągnąłeś co trzeba i tylko to się liczy. A co do IM, to nie wiem czy zauważyłeś, ale zapisujesz obrazek jako jpg. A ten nie wspiera obsługi przezroczystości i stąd mogą się pojawić problemy. Obejściem jest zastosowanie jako wyjścia pliku png lub skryptu, który symuluje przezroczystość w sposób jaki zaprezentowałem w swoim pierwszym poście. Bierzesz nakładające się punkty i obliczasz średnią obu obrazów dla danego punktu. Przykładowo w 3/4 obszaru wspólnego, patrząc od lewej strony, piksel obrazu A będzie miał przezroczystość 3/4, a B będzie miał 1/4. Jaki efekt? Wynikowy piksel to będzie: (1-3/4) * A( R, G, B ) + (1-1/4) * B( R, G, B ) Co wywoła wrażenie przenikania się obu obrazów, choć przezroczystości się tu nie ustawia wcale. Zwyczajnie kolory jednego z obrazów zaczynają stopniowo dominować nad drugim. taka sztuczka pozwalająca oszukać oko bez usiekania się do masek przezroczystości w formatach nie obsługujących jej, a mających złożenie wykonać. Można w ten sposób utworzyć maskę obrazu z "wagami przezroczystości" przy składaniu dwóch obrazów. Jeśli chce się składać kilka obrazów, to niestety, ale dla każdego obrazu trzeba taką utworzyć i suma wag wszystkich pikseli w maskach będących nad sobą powinna równać się 1. W ten sposób określasz lepszą lub gorszą widoczność konkretnego obrazka. Niestety im więcej zdjęć tym większe rozmycie i uśrednienie kolorów, przez co obraz staje się jedną, wielką plamą ![]() -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 14.08.2025 - 17:24 |