Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Łączenie przeźroczystych obrazków .png
Forum PHP.pl > Forum > Przedszkole
oskarro40
Witam.

Przygotowywuje na stronę system tworzenia avatarów dla uzytkowników. Avatary docelowo mają znajdować się w ramce w kształcie koła. W tym celu przygotowałem szablon >kilk<. Użytkownik przesyła na serwer swoje zdjęcie, które jest zamieniane na kwadrat o wymiarach 265x265. Następnie planowałem nałożyć na to zdjęcie mój szablon z przeźroczystością. Jednak element , ktory jest przeźroczysty w szablonie zamienia się na biały w obrazie wynikowym. Nie doszukałem się rozwiązania mojego problemu w google, wiec pisze tutaj.

mój kod:

  1. if( $_FILES['zdjecie']['error'] > 0) {
  2. //przekierowanie na stronę błędu
  3. } else {
  4. list($img_szer, $img_wys) = getimagesize($_FILES['zdjecie']['tmp_name']);
  5.  
  6. if($img_szer < 265 || $img_wys < 265) {
  7. //obraz za mały, przekierowanie na stronę błędu
  8.  
  9. } else if($img_szer >= 265 || $img_wys >= 265) {
  10.  
  11. //zapis obrazka na serwerze
  12. move_uploaded_file($_FILES['zdjecie']['tmp_name'], "images/users/{$_FILES['zdjecie']['name']}");
  13.  
  14. //skalowanie obrazka
  15. $zdjecie = imagecreatefrompng('images/users/'.$_FILES['zdjecie']['name']);
  16.  
  17. $x = imagesx($zdjecie);
  18. $y = imagesy($zdjecie);
  19.  
  20. $final_x = 265;
  21. $final_y = 265;
  22.  
  23. $tmp_x = 0;
  24. $tmp_y = 0;
  25.  
  26. if($y<$x) {
  27. $tmp_x = ceil(($x-$final_x*$y/$final_y)/2);
  28. } else if($x<$y) {
  29. $tmp_y = ceil(($y-$final_y*$x/$final_x)/2);
  30. }
  31.  
  32. $nowe_zdjecie = imagecreatetruecolor($final_x, $final_y);
  33. imagecopyresampled($nowe_zdjecie, $zdjecie, 0, 0, $tmp_x, $tmp_y, $final_x, $final_y, $x-2*$tmp_x, $y-2*$tmp_y);
  34.  
  35. imagepng($nowe_zdjecie, "images/users/nowe_zdjecie.png", 0);
  36.  
  37. unlink("images/users/{$_FILES['zdjecie']['name']}");
  38.  
  39. //nakladanie obrazków
  40. $zdjecie_big = imagecreatefrompng('images/users/nowe_zdjecie.png');
  41. $szablon = imagecreatefrompng('images/szablon_big.png');
  42.  
  43. imagecopymerge($zdjecie_big, $szablon, 0, 0, 0, 0, imagesx($zdjecie_big), imagesy($zdjecie_big), 100);
  44.  
  45. imagepng($zdjecie_big, "images/users/x_avatar.png", 0);
  46.  
  47.  
  48. }
  49. }


Niektóre wartości na sztywno, by łatwiej testować.

Pozdrawiam,
oskarro40

Edit: Tak to wyglada wynikowo: >klik<
a chciałbym aby było tak: >klik<

Przepraszam za spam... już rozwiazane:

  1. if( $_FILES['zdjecie']['error'] > 0) {
  2. //przekierowanie na stronę błędu
  3. } else {
  4. list($img_szer, $img_wys) = getimagesize($_FILES['zdjecie']['tmp_name']);
  5.  
  6. if($img_szer < 265 || $img_wys < 265) {
  7. //obraz za mały, przekierowanie na stronę błędu
  8.  
  9. } else if($img_szer >= 265 || $img_wys >= 265) {
  10.  
  11. //zapis obrazka na serwerze
  12. move_uploaded_file($_FILES['zdjecie']['tmp_name'], "images/users/{$_FILES['zdjecie']['name']}");
  13.  
  14. //skalowanie obrazka
  15. $zdjecie = imagecreatefrompng('images/users/'.$_FILES['zdjecie']['name']);
  16.  
  17. $x = imagesx($zdjecie);
  18. $y = imagesy($zdjecie);
  19.  
  20. $final_x = 265;
  21. $final_y = 265;
  22.  
  23. $tmp_x = 0;
  24. $tmp_y = 0;
  25.  
  26. if($y<$x) {
  27. $tmp_x = ceil(($x-$final_x*$y/$final_y)/2);
  28. } else if($x<$y) {
  29. $tmp_y = ceil(($y-$final_y*$x/$final_x)/2);
  30. }
  31.  
  32. $nowe_zdjecie = imagecreatetruecolor($final_x, $final_y);
  33. imagecopyresampled($nowe_zdjecie, $zdjecie, 0, 0, $tmp_x, $tmp_y, $final_x, $final_y, $x-2*$tmp_x, $y-2*$tmp_y);
  34.  
  35. imagepng($nowe_zdjecie, "images/users/nowe_zdjecie.png", 0);
  36.  
  37. unlink("images/users/{$_FILES['zdjecie']['name']}");
  38.  
  39. //nakladanie obrazków
  40. $duze = imagecreatefrompng("images/users/nowe_zdjecie.png");
  41. $w = imagesx($duze);
  42. $h = imagesy($duze);
  43. imagealphablending($duze,true);
  44.  
  45. $szablon = imagecreatefrompng("images/szablon_big.png");
  46. imagecopy($duze,$szablon,0,0,0,0,$w,$h);
  47.  
  48. imagepng($duze,"images/users/output.jpg",0);
  49.  
  50. }
  51. }
  52.  
  53.  
Matimor
Cały proces musi odbywać się w dwóch etapach.
1. Musisz wczytać oba obrazki (ten, co przesłał użytkownik oraz Twój szablon za pomocą funkcji createimagefrompng orazm createimagefrom...).
2. Musisz zapisać oba obrazki do jednego w kolejności: najpierw avatar, później szablon

Szablon musi być zrobiony w taki sposób, że obszar, w którym ma być widoczny avatar musi być przeźroczysty tzn. wycięty przeźroczysty okrąg na białym tle (lub innym kolorze tła).

Kod pomocniczy:
  1. // Wczytanie obrazka użytkownika
  2. $dest = imagecreatefrompng('images/users/'.$_FILES['zdjecie']['name']);
  3.  
  4. // Wczytywanie szablonu
  5. $src = imagecreatefrompng('images/szablon_big.png');
  6.  
  7. // Pobieranie wymiarów przesłanego obrazka
  8. $destWidth = imagesx($dest);
  9. $destHeight = imagesy($dest);
  10.  
  11. // Pobieranie wymiarów szablonu
  12. $srcWidth = imagesx($src);
  13. $srcHeight = imagesy($src);
  14.  
  15. // Obliczanie nowego rozmiaru przesłanego obrazka (dopasowanie do szerokości szablonu)
  16. $newImageWidth = $destWidth;
  17. $newImageHeight = round(($destWidth*$srcHeight)/$srcWidth, 0);
  18.  
  19. // Tworzenie nowego obrazka i obliczonych wymiarach
  20. $newImage = imagecreatetruecolor($newImageWidth, $newImageHeight);
  21.  
  22. // Kopiowanie obrazka użytkownika do nowego obrazka
  23. imagecopyresampled($newImage, $dest, 0, 0, 0, 0, $destWidth, $destHeight, $destWidth, $destHeight);
  24.  
  25. // Kopiowanie szablonu do nowego obrazka
  26. imagecopyresized($newImage, $src, 0, 0, 0, 0, $newImageWidth, $newImageHeight, $srcWidth, $srcHeight);
  27.  
  28. // Zapisywanie nowego obrazka do pliku
  29. imagepng($newImage, 'images/users/output.png', 0);
  30.  
  31. // Usuwanie stworzonych obiektów
  32. imagedestroy($newImage);
  33. imagedestroy($dest);
  34. imagedestroy($src);


Takie rozwiązanie powinno działać prawidłowo. Patrząc na Twój kod zauważyłem jeszcze, że używasz funkcji "imagepng" do zapisania obrazku "output.jpg", coś tu się chyba nie zgadza 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.