Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Kadrowanie czarnych ramek z obrazka
Forum PHP.pl > Forum > PHP
szymek001
Witam, czy jest jakiś sposób, żeby wykadrować czarne paski z dołu i z góry obrazka (jeśli występują)?
Chodzi mi o obrazki z youtube, np.:


jeśli film jest w rozdzielczości panoramicznej to do miniaturki dodane są czarne paski, których chciałbym się pozbyć..
A żeby było jeszcze trudniej, to mają one różne wysokości.. Czy da się jakoś za pomocą php zmierzyć jaka jest wysokość czarnego pola by ją później móc usunąć?
gitbejbe
da się. Kiedyś to robiłem ale od reki Ci nie powiem jak.

Tak czy siak, obrazki możesz kadrować - czyli powycinać te czarne paski. Wykrywać kolory też da rade z tym, że raczej wtedy usunie Ci kazdy czarny piksel w obrazka.

Obrazki z youtube na pewno mają różne wielkości ? Wydaje mi się, że kazdy film ma kilka wersji jednego obrazka w różnch rozmiarach. rozmiary sa stałe : | Kiedyś to robiłem i poporstu ucinałem te czarne paski i było wszystko ok.

w google -> php kadrowanie obrazków
szymek001
obrazki są tej samej rozdzielczości, ale w zależności od tego kto jakim sprzętem nagrywał paski są różnj wysokości.. tak by obraz wideo był dopasowany do ich ustalonej szerokości.
Samo kadrowanie nic mi nie pomoże, dopóki nie znajdę jakiejś metody na sprawdzenie wysokości czarnych pasków biggrin.gif
timon27
Wczytujesz obrazek:
  1. $image= imagecreatefromjpeg($filename);
  2. list($w, $h) = getimagesize($filename);


Funkcja sprawdzająca czy linijka jest czarna:
  1. function sprawdź_linijkę($k){
  2. global $h,$w,$image;
  3. for($i=0;$i<$w;$i++){
  4. $rgb = imagecolorsforindex($image,imagecolorat($image, $i, $k));
  5. if($rgb['red']>3 or $rgb['green']>3 or $rgb['blue']>3)
  6. return False;
  7. }
  8. return True;
  9. }


określasz górny i dolny margines:
  1. $i=0;
  2. while( sprawdź_linijkę($i)) $i++;
  3. $górny=$i;
  4.  
  5. $i=$h-1;
  6. while( sprawdź_linijkę($i)) $i--;
  7. $dolny=$i;



Tworzysz nowy obrazek z częścią właściwą
  1. header('Content-type: image/jpeg');
  2. $image2 = imagecreatetruecolor($sze, $dolny-$górny);
  3. imagecopyresampled($image2, $image, 0, 0, 0, $górny, $w, $dolny-$górny, $w, $dolny-$górny);


Wyświetlasz/zapisujesz obrazek:
  1. imagejpeg($image2, $url_zapisu, 90);
  2. imagejpeg($image2);


Pisałem na żywo, więc mogą być błędy, ale idea najważniejsza.

Crozin
1. Znając wielkość obrazka będziesz potrzebował dwóch zagnieżdżonych pętli. Pierwsza, będzie "leciała" po każdym wierszu (rząd pikseli w poziomie), druga (wewnętrzna) już po każdym indywidualnym pikselu w danym wierszu. Wewnętrzna pętla niech sprawdza, czy którykolwiek z pikseli w danym wierszu jest różny od czarnego, jeżeli jest oznacza to, że dotarłeś do końca czarnego paska i możesz przerwać działanie obu pętli (break). Po wykonaniu się wewnętrznej pętli możesz przyjąć, że cały wiersz jest do wyrzucenia.
2. Po wykonaniu się kodu opisanego powyżej znasz wysokość, którą musisz uciąć.
3. Analogicznie postępujesz z drugiej strony - od dołu.
4. Na koniec pozostaje wykadrowanie zdjęcia.

Pamiętaj jednak o tym, że na miniaturce może być widoczna klatka, która sama w sobie ma "czarne paski" (np. w przypadku gdy na miniaturce widzimy tytuł filmu na czarnym tle) - powinieneś uwzględnić ten fakt, by przypadkiem nie wygenerować sobie miniaturki o wielkości 1980x50 pikseli. wink.gif

PS. Nie jest to najlepsza metoda, ale na niedużą skalę nada się w sam raz.
szymek001
skrypt od timon27 działa prawie idealnie - prawie, bo nie do końca kadruje dobrze to jest góre ścina mniej, dół bardziej, ale i tak nie jako całość:

czemu jest tam "$dolny-$gorny" ?

Próbowałem bawić się tym ustawieniem, jednak cokolwiek innego powoduje wyświetlanie całego czarnego prostokąta.. biggrin.gif

Edit: działa, trzeba uznać poprawkę na tolerancję "czarnego" który nie do końca jest czarny smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.