Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Tworzenie miniatury obrazu
Forum PHP.pl > Forum > PHP
markonix
Chciałbym tworzyć miniaturki wgranych zdjęć zawsze o rozmiarze 100 x 100px - kwadrat.

Wymuszam aby zdjęcie miało minimum 100px szerokości (lub wysokości) oraz stosunek boków wynosił 1 z małym marginesem błędu.

Wszystko ok ale użytkownicy nie zawsze będą w stanie dostarczyć takie zdjęcie i nie chce wymagać od nich obróbki zdjęcia na komputerze.
W końcu naszym (programistów) celem jest ułatwić życie użytkownikom.

Przykładowo mamy zdjęcie wysokie:

200px wysokości na 100px szerokości.

Oczywiście gdy je zmniejszę do 100x100 (bez zachowania proporcji) to zdjęcie się spłaszczy.

Znaczna większość zdjęć będzie miała białe tło dlatego myślałem, aby w jakiś sposób "wypełnić zdjęcie tłem".
Idee prezentuje obrazek:


Czy to dobry pomysł i jakieś pomysły jak uzupełnić w te boki (lub w odwrotnej sytuacji górę i dół) obrazek?

Od razu uprzedzam odpowiedź - "croppery jQuery". W 99% przypadkach to co jest na obrazku musi w całości przejść (czyli nie tak jak jest przy avatarach gdzie wycinasz tylko twarz) tak więc, nawet jakbym dał możliwość wycinania to i tak polem nożyczek, nie był by w stanie zaznaczyć całego kwiatka.
mar1aczi
Znając wielkość miniatury, a tym samy obszaru, w którym będziesz prezentował tą miniaturę użyj CSS background-color.
markonix
Zapomniałem dodać, że bardziej mi chodzi o rozwiązanie serwerowe.
Chciałbym mieć w folderze same obrazy 100x100 (równolegle ikony 32x32 ale to nieistotne).

Mam zainstalowany na serwerze ImageMagick
nospor
NIe bardzo rozumiem z czym masz problem. Wyliczasz najwiekszą możliwą skale. Do tej skali skalujesz obrazek. Jesli szerokosc obrazka wychodzi za mala to:
tworzysz bialy obraz 100x100 a na to wrzucasz wygenerowany obrazek o wspolrzednej X = (100-szerokosc obrazka)/2
Wszystko to jest banalne do zrealizowania przy pomocy php GD
markonix
Bez tych zgryźliwości w poście oszczędziłbyś z 10 sekund życia.

Po prostu nie wpadłem na pomysł z nakładaniem na siebie obrazków, szedłem raczej w stronę "dopinania" boków.
nospor
Wskaz mi prosze moje zgryźliwosci, bo chyba oboje inaczej odbieramy moj post. Nie kierowalem do Ciebie zadnych zgryźliwosci. Wyjasnilem ci jak to sie robi. A ze to sie robi banalnie, to jest fakt, a nie zgryźliwość tongue.gif
markonix
Ostatecznie poszedłem jednak moją ścieżką, nie umiałem zrealizować nakładania obrazów, a przy okazji szukania rozwiązań natknąłem się na metodę, która robi to czego potrzebuje:
imagick.extentimage


  1. $image = new Imagick($path . $file_name);
  2.  
  3. $d = $image->getImageGeometry();
  4. if ($d['width'] != $d['height'])
  5. {
  6. if ($d['width'] > $d['height'])
  7. {
  8. $ratio = $d['width'] / $dimension[0];
  9. $width = $dimension[0];
  10. $height = $d['height'] / $ratio;
  11. }
  12. else
  13. {
  14. $ratio = $d['height'] / $dimension[1];
  15. $width = $d['width'] / $ratio;
  16. $height = $dimension[1];
  17. }
  18. $need_extent = TRUE;
  19. }
  20. else
  21. {
  22. $width = $dimension[0];
  23. $height = $dimension[1];
  24. $need_extent = FALSE;
  25. }
  26.  
  27. $image->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 1);
  28. $image->setImageBackgroundColor($image->getImageAlphaChannel() ? 'None' : 'White');
  29. if ($need_extent)
  30. {
  31. $image->extentImage($dimension[0], $dimension[1], -($dimension[0] - $width) / 2, -($dimension[1] - $height) / 2);
  32. }
  33.  
  34. $image->setImageFormat('png');


1. Liczenie wysokości i szerokości w oparciu o większy bok + określenie czy w ogóle potrzebujemy "wypełniania".
2. Ustalenie tła jest potrzebne inaczej zawsze wypełni białym, a zależy mi aby zachować przeźroczystość. Jeżeli ktoś wgrywa z białym tłem to już jego sprawa ale pomyślę o transformacji białego na transparent.
3. Trzeba wycentrować obraz współrzędnymi inaczej domyślnie (przy 0) obraz umieści z lewej.
kilaz91
Użyj imagemagick,
niektóre hostingi mają uruchomione i wpięte jako moduł:
$image = new \Imagick ();
$image->newImage ($this->width, $this->height,'white'); //TWOJE NOWE WYMIARY
$image->setImageOpacity(0);
$image->setBackgroundColor(new \ImagickPixel('transparent'));
//Przeskalowanie oryginału do rozdzielczości tutaj sobie popróbuj, ja korzystam z pełnego (100% pokrycia) oraz 100% widoczności (biały pasek z boków albo u góry/dołu)
$photo->scaleImage($newWidth, $newHeight);

a takie jak OVH, każą odwoływać się do systemu przez komendę:
$command = 'convert '.$this->_getPath().' -resize '.$newWidth.'x'.$newHeight.' -gravity center -background white -extent '.$this->width.'x'.$this->height.' '.$this->_getNewPath();


do rozpoznania czy jest wpięte jako moduł:
if (class_exists('Imagick'))
albo w phpinfo()
markonix
Aleś wywalił teraz wink.gif

W każdym razie Twój kod nic nie wnosi, to zwykłe skalowanie.
Wyrzuć ten post.
phpion
Kolego, trochę pokory. Do dwóch użytkowników wyskakujesz z pretensjami za chęć pomocy.
kilaz91
Tutaj jest pokazany sposób skalowania do różnych wymiarów w sposób jaki chciałeś (fragment Twojego pytania), dalej nie miałem czasu żeby się rozpisywać aczkolwiek jeżeli piszą dwie osoby w ten sam deseń o tym więc logiczne że można zapoznać się z tym narzędziem (dokumentacja).

Wstępnie masz opracowanie skalowanie, podobnie musisz podstąpić z tłem.
Nakładanie na siebie obrazów (tworzenie tła czy znaku wodnego) to jedna dodatkowa komenda.
Naprowadzenie na dobrą drogę nie wystarczy?

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.