Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Upload obrazków - problem
Forum PHP.pl > Forum > Przedszkole
RubiX
Witam
napisałem taki kod do uploadu obrazków:

  1. $obrazek = $_FILES['obrazek'];
  2. $nazwaobrazka = $_FILES['obrazek']['name'];
  3. $num_start = rand(20 , 9999); //losowa liczba między 20 a 9999
  4. $nowanazwaobrazka = $num_start.$nazwaobrazka; // tworzy nową nazwe pliku
  5. if($obrazek['type']=='image/jpeg') {
  6. $source = imagecreatefromjpeg($obrazek[tmp_name]);
  7. } elseif($obrazek['type']=='image/png') {
  8. $source = imagecreatefrompng($obrazek[tmp_name]);
  9. } elseif($obrazek['type']=='image/gif') {
  10. $source = imagecreatefromgif($obrazek[tmp_name]);
  11. } elseif($obrazek['type']=='image/pjpeg') {
  12. $source = imagecreatefromjpeg($obrazek[tmp_name]);
  13. } elseif($obrazek['type']=='image/x-png') {
  14. $source = imagecreatefrompng($obrazek[tmp_name]);
  15. }
  16.  
  17. //obraz
  18. if (imagesy($source)<600 AND imagesx($source)<600) {
  19.  
  20. if(imagesy($source)>imagesx($source)) {
  21. $new_height = imagesx($source);
  22. $new_width = floor(imagesx($source)*($new_height/imagesy($source)));
  23. } else {
  24. $new_width = imagesy($source);
  25. $new_height = floor(imagesy($source)*($new_width/imagesx($source)));
  26. }
  27. $dest = imagecreatetruecolor($new_width,$new_height);
  28. imagecopyresampled($dest,$source,0,0,0,0,$new_width,$new_height,imagesx($source),imagesy($source)); imagejpeg($dest,'../images/duze/'.$nowanazwaobrazka.'',99);
  29. imagedestroy($dest);
  30. } else {
  31. if(imagesy($source)>imagesx($source)) {
  32. $new_height = 600;
  33. $new_width = floor(imagesx($source)*($new_height/imagesy($source)));
  34. } else {
  35. $new_width = 600;
  36. $new_height = floor(imagesy($source)*($new_width/imagesx($source)));
  37. }
  38. $dest = imagecreatetruecolor($new_width,$new_height);
  39. imagecopyresampled($dest,$source,0,0,0,0,$new_width,$new_height,imagesx($source),imagesy($source)); imagejpeg($dest,'../images/duze/'.$nowanazwaobrazka.'',99);
  40. imagedestroy($dest);
  41. }
  42.  
  43. //miniaturka
  44. if(imagesy($source)>imagesx($source)) {
  45. $new_height = 60;
  46. $new_width = floor(imagesx($source)*($new_height/imagesy($source)));
  47. } else {
  48. $new_width = 60;
  49. $new_height = floor(imagesy($source)*($new_width/imagesx($source)));
  50. }
  51. $dest = imagecreatetruecolor($new_width,$new_height);
  52. imagecopyresampled($dest,$source,0,0,0,0,$new_width,$new_height,imagesx($source),imagesy($source)); imagejpeg($dest,'../images/mini/'.$nowanazwaobrazka.'',99);
  53. imagedestroy($dest);
  54. imagedestroy($source);


i mam problem otóż jak obraz jest większy niż 600px x 600px to zmniejsza go i dobrze wgrywa, natomiast jak obraz jest mniejszy od 600px x 600px to zamiast wgrac go dobrze tzn stworzyc od nowa jak 1 bok 1 za duzy to zmniejszyc troche i wrzucic to zmniejsza go całkowicie nieraz nawet do 100x100px pomimo iz obraz ma 400x400px ? gdzie zrobiłem błąd ?
thek
Powiem tylko tyle, że kod masz mocno nieoptymalny.
Powinno to wyglądać tak:
1. Sprawdzasz format (ta część poprawnie),
2. Sprawdzasz rozmiar (tu bym się kłócił czy poprawnie),
3. Jeśli większy niż wymagane to oblicz stopień skalowania dla każdego z boków. Ten który ma mniejszy - dla niego ustaw 600, temu z większym oblicz nowy rozmiar obliczając wcześniej ratio pomiędzy bokami oryginalnego by zachować proporcje boków.
4. Jeśli jest mniejszy... Po prostu skopiuj obraz przysłany do katalogu docelowego.
5. A teraz zrób sobie miniaturkę winksmiley.jpg

I jeszcze jedno... Czy masz mieć maksymalny rozmiar jednego z nich większy od 600 czy wystarczy że jeden z nich przekroczy 600? bo od tego zależy czy masz w sprawdzaniu warunków AND czy OR. A to jest poważna różnica, bo obraz 5000x400 nie będzie skalowany gdy masz AND, zaś w przypadku OR jak najbardziej zostanie potraktowany zmniejszaniem.
RubiX
dobra już działa a co do

5. zrób sobie miniaturke to ten kod juz robi miniaturkę.
Błąd był w tym że miałem w 1 imagesx i imagesy zamienione x z y smile.gif
thek
  1. $obrazek = $_FILES['obrazek'];
  2. $nazwaobrazka = $_FILES['obrazek']['name'];
  3. $num_start = rand(20 , 9999); //losowa liczba między 20 a 9999
  4. $nowanazwaobrazka = $num_start.$nazwaobrazka; // tworzy nową nazwę pliku
  5. switch( $obrazek['type'] ) {
  6. //w tym switchu sprawdzamy typ typ pliku. Jeśli to nie jest według MIME obrazek o żadnym z podanych typów, wrzuć do $source FALSE
  7. case 'image/jpeg':
  8. case 'image/pjpeg':
  9. $source = imagecreatefromjpeg($obrazek[tmp_name]);
  10. break;
  11. case 'image/png':
  12. case 'image/x-png':
  13. $source = imagecreatefrompng($obrazek[tmp_name]);
  14. break;
  15. case 'image/gif':
  16. $source = imagecreatefromgif($obrazek[tmp_name])
  17. break;
  18. default:
  19. $source = FALSE;
  20. }
  21.  
  22. //jesli plik nie został rozpoznany lub wczytanie się nie powiodło to wywal informację o błędzie
  23. if( $source ) {
  24. $src_w = imagesx($source); //pobierz szerokość
  25. $src_h = imagesy($source); //pobierz wysokość
  26. $dest_w = $src_w; //ustal rozmiary docelowego identyczne ze źródłowym
  27. $dest_w = $src_h;
  28. $destm_w = 60; //ustal wymiary miniaturki na 60 x 60
  29. $destm_h = 60;
  30. $ratio = $src_w / $src_h; //ustal współczynnik proporcji
  31. if( $src_w > 600 OR $src_h > 600 ) { //sprawdź, czy któryś z wymiarów przekracza 600
  32. if( $src_w > $src_h ) { //jeśli szerokość większa to...
  33. $dest_w = 600; //..szerokość ustaw na 600...
  34. $dest_h = ceil( 600 / $ratio ); //...wysokość policz...
  35. $destm_h = ceil( $destm_h / $ratio); // ...i policz wysokość miniaturki
  36. } else { //jesli wysokość większa...
  37. $dest_h = 600; // ...ustaw wysokość na 600...
  38. $dest_w = ceil( 600 * $ratio ); //...policz nową szerokość...
  39. $destm_w *= ceil( $destm_w * $ratio); //... i oblicz szerokość miniaturki
  40. }
  41. }
  42. if( $src_w > $src_h ) { //jeśli szerokość większa to...
  43. $destm_h = ceil( $destm_h / $ratio); // policz wysokość miniaturki
  44. } else { //jesli wysokość większa..
  45. $destm_w *= ceil( $destm_w * $ratio); //oblicz szerokość miniaturki
  46. }
  47. $dest = imagecreatetruecolor( $dest_w,$dest_h );
  48. imagecopyresampled( $dest, $source, 0, 0, 0, 0, $dest_w, $dest_h, $src_w, $src_h ); //stwórz obraz wynikowy
  49. imagejpeg($dest,'../images/duze/'.$nowanazwaobrazka.'',75); //zapisz go (większe niż 75 dla tej rozdzielczości są bezsensem )
  50. $dest = imagecreatetruecolor( $destm_w,$destm_h );
  51. imagecopyresampled( $dest, $source, 0, 0, 0, 0, $destm_w, $destm_h, $src_w, $src_h ); //stwórz miniaturkę
  52. imagejpeg($dest,'../images/mini/'.$nowanazwaobrazka.'',60); //zapisz miniaturkę (większe niż 60 dla miniatur są bezsensem )
  53. imagedestroy($dest); //niszczenie plików biblioteki GD
  54. imagedestroy($source);
  55. } else
  56. echo "Błąd przetwarzania";

Dlaczego tak? Bo jest mniej bajzlu w kodzie, widać co się dzieje. Mogłem wrzucić konwersje głównego obrazka do osobnego i w razie gdyby oba wymiary były mniejsze niż 600 oraz byłby to jpg po prostu skopiować źródłowy bezpośrednio gdzie indziej, bo nawet konwersji bym robić nie musiał. A wpisywanie 99 w imagejpg jest głupotą, bo tworzy ogromne pliki. Na potrzeby www z reguły wystarcza 70-75 a dla miniatur maksimum to 60-65. Kod skracałes sobie wywołując co chwilę imagesx i imagesy, a przypisanie do zmiennych skraca czas dostępu niż notoryczne ich używanie winksmiley.jpg
Kod jest zupełnie niezabezpieczony przeciwko takim "atakom" jak obrazki 5000x1 czy 1x5000 bo warunek skalowania wtedy nie ruszy smile.gif A layout strony Ci się rozjedzie całkiem. Nie jest tez zabezpieczony przeciwko innym typom plików bo nawet nie sprawdzasz, czy to co dostałeś w ogóle jest plikiem obrazu. Kompletnie więc zaniedbałeś bezpieczeństwo skryptu i wystawiłeś się na atak. Ja i tak zanim swój skrypt bym puścił to sprawdziłbym co mi właściwie ludzie do zmiennej $_FILES wrzucili. Bo jeśli jakiś skrypt... to mógłbyś mieć nieprzyjemną sytuację.
webdice
Przenoszę do działu Przedszkole.
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.