Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Kadrowanie zdjęc do środka.
Forum PHP.pl > Forum > Przedszkole
zerosix
Witam,
czy istnieje jakiś sposób aby kadrować zdjęcia o określonym wymiarze od środka?
A mianowicie skrypt znajduje srodek zdjecia a nastepie kadruje?
wookieb
Tak istnieje. Musisz tylko wyliczyć parametry.
http://pl.php.net/manual/en/function.imagecopy.php
albo z użyciem Imagicka
thek
Nie no... Matma się kłania i to na poziomie proporcji poznawanych w 5 klasie podstawówki na oko oraz dodawania i odejmowania na poziomie 1 klasy podstawówki.
Bierzesz rozmiar wynikowy. Liczysz wielokrotność boku między oryginałem i wynikowym. Tam gdzie jest mniejsza liczba nastąpi przypisanie. Potem musisz policzyć z tym samym stopniem skalowania rozmiar drugiego rozmiaru dla oryginału, odjąć ten rozmiar od całej długości boku i ową wielkość podzielić przez 2, co wskaże miejsce kadrowania.
Przykład:
Oryginał 800 x 765
Kadr: 200 x 300
800(oryg)/200(kadr) = 4
765(oryg)/300(kadr) = 2,55
Bierzemy 765(wysokość oryginału) i obliczamy
200(szerokość kadru - przeciwległy do wybranego wymiar)*2,55 = 510
(800-510)/2 = 290 / 2 = 145 (miejsce rozpoczęcia kadrowania dla przeciwległego boku do wybranego)

A więc używamy imagecopyresampled gdzie z oryginału wyciągamy fragment o współrzędnych startu 145,0 i parametrach 510 x 765 po czym wtłaczamy do 200 x 300

Teraz te same dane, ale kadr "odwrócony":
Oryginał 800 x 765
Kadr: 300 x 200
800(oryg)/300(kadr) = 2,66
765(oryg)/200(kadr) = 3,825
Bierzemy 800 (szerokość oryginału) i obliczamy
200(wysokość kadru - przeciwległy do wybranego wymiar)*2,66 = 533,333 ~= 533
(765-533)/2 = 232 / 2 = 116 (miejsce rozpoczęcia kadrowania dla przeciwległego boku do wybranego)

A więc używamy imagecopyresampled gdzie z oryginału wyciągamy fragment o współrzędnych startu 0,116 i parametrach 800 x 533 po czym wtłaczamy do 300 x 200

Popatrz jak zmieniło mi się wyliczanie. Raz mniejsza proporcja na szerokości, raz na wysokości, co zmieniło współrzędne dla kadrowania... Raz było 0,x a innym x,0. Popatrz na algorytm i pisz, bo funkcjami Ci tego okładać nie mam zamiaru. Czas na Twój ruch, a nie czekanie na gotowca.

P.S.: Oczywiście to jest kadrowanie obrazu do określonego wynikowego ze skalowaniem całego obrazu do kadru wynikowego. Musisz też sprawdzić, czy aby któryś z wymiarów kadru nie jest większy od oryginału. Wyjdzie to przy skalowaniu... Te większe będą miały proporcję mniejszą niż 1. W takich wypadkach kod nieco się zmieni i będziesz musiał "dokładać" puste miejsce po bokach. Zostawiam Ci ten ostatni przypadek do samodzielnego przemyślenia. Najważniejsze w tym przypadku jest przemyślenie, który bok będzie uznany za ten, służący do wyliczenia proporcji dla drugiego. No i nieco inaczej będzie wyglądało wywołanie imagecopyresampled smile.gif Parametry bowiem będą ciut inaczej wyliczone. Tu będzie konieczne więcej obliczeń. No chyba, że mowa o zwykłym kopiowaniu fragmentu obrazu do wyniku bez przeskalowywania. Wtedy sprawa się mocno upraszcza.

Ale zwykłe kadrowanie bez przeskalowywania odrób jako zadanie domowe z użyciem wspomnianej przez wookiego funkcji smile.gif

EDIT: Zauważ, że istnieją 3 warianty kadrowania ze skalowaniem:
- oba wymiary oryginału są większe niż w kadrze (kadrowanie z pomniejszaniem)
- oba wymiary oryginału są mniejsze niż w kadrze (kadrowanie z powiększaniem)
- jeden z wymiarów oryginału jest mniejszy niż w kadrze (specyficzny przypadek pomniejszania z kadrowaniem )
Musisz je rozpoznać i odpowiednio zareagować.
zerosix
dzieki za wyczerpujaca odpowiedz,bede dłubałsmile.gif
celbarowicz
wiem, że nie na temat. w razie rozpaczy możesz zrobić to ręcznie- na oko programem JPEGCrops->darmowy
MrNeo
Witam i przepraszam, że odkopuję stary temat ale mam podobny problem.

Dzięki wskazówkom thek'a doszedłem do takiego kodu:
  1. $info = getimagesize($filepath);
  2. $szerokosc_oryginal = $info[0];
  3. $wysokosc_oryginal = $info[1];
  4.  
  5. $tempImg = imagecreatetruecolor(120, 80);
  6.  
  7. $wspolczynnik_szerokosc = $szerokosc_oryginal / 120;
  8. $wspolczynnik_wysokosc = $wysokosc_oryginal / 80;
  9.  
  10. if($wspolczynnik_szerokosc > $wspolczynnik_wysokosc)
  11. {
  12. $start_x = ($szerokosc_oryginal - round(120 * $wspolczynnik_wysokosc, 1)) / 4;
  13. imagecopyresized($tempImg, $img, 0, 0, $start_x, 0, 120, 80, imagesy($img) * 1.5, imagesy($img));
  14. }
  15. else
  16. {
  17. $start_y = ($wysokosc_oryginal - round(80 * $wspolczynnik_szerokosc, 1)) / 4;
  18. imagecopyresized($tempImg, $img, 0, 0, 0, $start_y, 120, 80, imagesx($img), imagesx($img) / 1.5);
  19. }
  20.  
  21. imagejpeg($tempImg, $sciezka_miniatura);


Wydaje mi się, że wszystko przeanalizowałem dobrze, ale jednak kod nie działa tak jak powinien.

W czym może tkwić błąd?

Mój skrypt ma wycinać ze środka obrazu kadr, a potem zmniejszać go do rozmiaru 120x80. Zależy mi na zachowaniu proporcji bo bez tego miniatura wygląda koszmarnie. W założeniu żaden plik z którego będę kadrował nie jest mniejszy w żadnym wymiarze od 120x80.

Z góry dziękuję za wszelką pomoc 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.