Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP] Opytmalizacja operacji, w trakcie przetwarzania obrazka zmiana rozdzielczości
smarcz
post
Post #1





Grupa: Zarejestrowani
Postów: 80
Pomógł: 0
Dołączył: 12.05.2005

Ostrzeżenie: (0%)
-----


Witam!

Problem polega na optymalizacji operacji w trakcie przetwarzania obrazka - zmiana rozdzielczosci i jego ponowne zapisanie! Przesyłanych pól w formularzu jest 7. Problem zaczyna się kiedy wysyłam pliki graficzne których wielkości przekracza 256 kb - i jest ich kila w pewnym momencie pojawia się błąd o treści:
Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 8704 bytes) in /home/.../ftp/.../spr3.php on line 101

Serwer na którym pracuje ma wprowadzone ograniczenie 20MB.

Może znacie sposób obróbki obrazka inny niż ja - lub jak podzielić mój skrypt na operacje aby się zmieścić w limicie??

Oto kod!:

  1. function k1(){
  2. ?>
  3. <FORM name="f1" METHOD="POST" ACTION="<?php echo $PHP_SELF ?>" enctype="multipart/form-data">
  4. <INPUT TYPE="HIDDEN" NAME="action" VALUE="d1">
  5.  
  6. <input type="file" name="zdj_p1" size="20">
  7. <div align="center">
  8. <input type="submit" name="w" value="Zapisz">
  9. <input type="reset" value="Skasuj">
  10. </div>
  11. </FORM>
  12. <?
  13. }
  14. function d1(){
  15.  
  16. $zdj1 = $_FILES['zdj_p1'];
  17.  
  18. $stos=0;
  19.  
  20. if(!empty($zdj1)){
  21. $stos++;
  22.  
  23. //Zapisywanie wartości zdjęcia do zmiennych
  24. $nazwa = $_FILES['zdj_p1']['name'];
  25. $typ  = $_FILES['zdj_p1']['type'];
  26. $size = $_FILES['zdj_p1']['size'];
  27. $plik = $_FILES['zdj_p1']['tmp_name'];
  28.  
  29. $wielkosc = 200000;//Wielkość przesyłanego pliku - 200KB
  30. $x = 600;//Szerokość w Pixelach
  31.  
  32. $filename = '';
  33. $filename .= $stos;
  34. $filename .= date("YmdHis");
  35. $filename .= $id;
  36. $filename .= 'o';
  37.  
  38. $mojaNazwa = $filename.'.jpg';
  39.  
  40. $sciezka = 'img/';
  41. //Przetwarzanie obrazka z formatu jpg i jpeg
  42. if (ereg("image/jpeg", $typ)){
  43. echo "to jest JPG<br>";
  44.  
  45. $zdj = ImageCreateFromJpeg($plik);
  46. $zdjx = ImageSX($zdj);
  47. $zdjy = ImageSY($zdj);
  48.  
  49. $y = ceil($zdjy*($x/$zdjx));
  50. $nowezdj = imagecreatetruecolor($x, $y);
  51. imagecopyresized($nowezdj,$zdj,0,0,0,0,$x,$y,$zdjx,$zdjy);
  52. imagejpeg($nowezdj, $sciezka . $mojaNazwa ,100);
  53. }
  54.  
  55. //Przetwarzanie obrazka z formatu gif
  56. elseif(ereg("image/gif", $typ)){
  57. echo "to jest GIF<br>";
  58.  
  59. $zdj = ImageCreateFromGIF($plik);
  60. $zdjx = ImageSX($zdj);
  61. $zdjy = ImageSY($zdj);
  62.  
  63. $y = ceil($zdjy*($x/$zdjx));
  64. $nowezdj = imagecreatetruecolor($x, $y);
  65. imagecopyresized($nowezdj,$zdj,0,0,0,0,$x,$y,$zdjx,$zdjy);
  66. imagejpeg($nowezdj, $sciezka . $mojaNazwa ,100);
  67. }
  68.  
  69. //Przetwarzanie obrazka z formatu png
  70. elseif(ereg("image/png", $typ)){
  71.  
  72. $zdj = ImageCreateFromPng($plik);
  73. $zdjx = ImageSX($zdj);
  74. $zdjy = ImageSY($zdj);
  75.  
  76. $y = ceil($zdjy*($x/$zdjx));
  77. $nowezdj = imagecreatetruecolor($x, $y);
  78. imagecopyresized($nowezdj,$zdj,0,0,0,0,$x,$y,$zdjx,$zdjy);
  79. imagejpeg($nowezdj, $sciezka . $mojaNazwa ,100);
  80. }
  81. else{
  82. echo "Niepoprawny format pliku<br>";
  83. }
  84. }
  85.  
  86. }
  87. ?>


a to wynik działania tego formularza:

array (
'action' => 'd1',
'w' => 'Zapisz',
)

array (
'zdj_p1' =>
array (
'name' => 'list motywacyjny1.jpg',
'type' => 'image/jpeg',
'tmp_name' => '/tmp/php9Izb0I',
'error' => 0,
'size' => 258787,
),
'zdj_p2' =>
array (
'name' => 'List[Andrzej].GIF',
'type' => 'image/gif',
'tmp_name' => '/tmp/phpjCXT0F',
'error' => 0,
'size' => 183603,
),
'zdj_1' =>
array (
'name' => 'error.jpg',
'type' => 'image/jpeg',
'tmp_name' => '/tmp/phpiTN7n4',
'error' => 0,
'size' => 365525,
),
'zdj_2' =>
array (
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
),
'zdj_3' =>
array (
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
),
'zdj_4' =>
array (
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
),
'zdj_5' =>
array (
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
),
)

Nazwa - list motywacyjny1.jpg
Typ - image/jpeg
Wielko�ć kb - 258787
to jest JPG

Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 8704 bytes) in /home/.../ftp/.../spr3.php on line 101


Ten post edytował smarcz 26.02.2007, 13:48:50
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
yaotzin
post
Post #2





Grupa: Zarejestrowani
Postów: 157
Pomógł: 0
Dołączył: 12.02.2007
Skąd: Zielona Góra

Ostrzeżenie: (0%)
-----


  1. <input type="file" name="zdj_p1" size="20">


A tu nie powinno być przypadkiem tak (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)

  1. <input type="file" name="zdj_p1" size="200000">


size określa wielkośc wrzucanego pliku na serwer, łatwe do obejścia, ale jest częstą przyczyną błędów u początkujących. PZDR
Go to the top of the page
+Quote Post
Kicok
post
Post #3





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

Ostrzeżenie: (0%)
-----


sprawdź czy wydajność się poprawi gdy zaczniesz stosować imagedestroy" title="Zobacz w manualu PHP" target="_manual
Go to the top of the page
+Quote Post
smarcz
post
Post #4





Grupa: Zarejestrowani
Postów: 80
Pomógł: 0
Dołączył: 12.05.2005

Ostrzeżenie: (0%)
-----


Dzięki za podpowiedź Kicok, też czytałem o tym dziś w Manualu - zastosowałem nic z tego. Tu chodzi chyba o pamięć CACHE serwera. Bo czasem jest tak, że pierwszy (1) plik dodawany w formularzu (7 pól input files) ma pojemność większą niż 200 kb i bład Fatal Error pojawia się dla linii kodu:

  1. <?php
  2. $zdj = ImageCreateFrom?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ($plik);
  3. ?>


Że pamięc została przekroczona - tak więc nie wiem od czego to zależy!? (IMG:http://forum.php.pl/style_emoticons/default/sad.gif)

Wygląda to tak, jakby plik który idzie do przetwarzania powiększał się. Może jest jakiś sposób na określenie pamięci dla takiej operacji. Czytałem dziś w Manualu na temat: clearstatcache — Czyści bufor statusu pliku lub memory_get_usage

Może jest jakieś polecenie które wyświetla stan pamięci BUFORA. Ja potrzebuje się zmieścić w 20 MB na serwerze. Chyba, że jest jakiś inny sposób na zmianę rozdzielczości obrazka??

----00.33 27.02.2007----

Tak więc po kilkunastu testach z użyciem funkcji memory_get_usage() - która wyświetla pamięć używaną stwierdzam:

Plik jpg który ma wielkość [bajtach] 615184 (601 kb) po wykonaniu poniższego kodu:

  1. <?php
  2. if(!empty($zdj1)){
  3. $stos++;
  4.  
  5. //Zapisywanie wartości zdjęcia do zmiennych
  6. $nazwa = $_FILES['zdj_p1']['name'];
  7. $typ  = $_FILES['zdj_p1']['type'];
  8. $size = $_FILES['zdj_p1']['size'];
  9. $plik = $_FILES['zdj_p1']['tmp_name'];
  10.  
  11. echo "Nazwa - $nazwa<br>";
  12. echo "Typ - $typ<br>";
  13. echo "Wielkość kb - $size<br>";
  14.  
  15. $wielkosc = 200000;//Wielkość przesyłanego pliku - 200KB
  16. $x = 600;//Szerokość w Pixelach
  17.  
  18. //1.) Tworze nazwę pliku składającą się z numeru pliku w stosie
  19. //2.) Z daty i godziny
  20. //3.) Numeru ID przekazywanego w sesji
  21. //4.) Literki "o" - określającej obiekt
  22.  
  23. $filename = '';
  24. $filename .= $stos;
  25. $filename .= date("YmdHis");
  26. $filename .= $id;
  27. $filename .= 'o';
  28.  
  29. $mojaNazwa = $filename.'.jpg';
  30.  
  31. $sciezka = 'img/';
  32.  
  33. //Przetwarzanie obrazka z formatu jpg i jpeg
  34. if (ereg("image/jpeg", $typ)){
  35. echo "to jest JPG<br>";
  36.  
  37. $zdj = ImageCreateFromJpeg($plik);
  38. echo memory_get_usage() . "<strong>- Po ImageCreate<br></strong>"; // wyświetlam zajmowaną pojemność w bajtach
  39. $zdjx = ImageSX($zdj);
  40. $zdjy = ImageSY($zdj);
  41. echo memory_get_usage() . "<strong>- Po $zdjx i y<br></strong>"; // wyświetlam zajmowaną pojemność w bajtach
  42. $y = ceil($zdjy*($x/$zdjx));
  43. $nowezdj = imagecreatetruecolor($x, $y);
  44. imagecopyresized($nowezdj,$zdj,0,0,0,0,$x,$y,$zdjx,$zdjy);
  45. imagejpeg($nowezdj, $sciezka . $mojaNazwa ,100);
  46. echo memory_get_usage() . "<strong>- Przed imagedestroy<br></strong>"; // wyświetlam zajmowaną pojemność w bajtach
  47. imagedestroy($zdj);
  48. }
  49. }
  50. ?>


zmienia swoją pojemność po stronie serwera następująco:
9780648 - Po ImageCreateFromJpeg($plik);
9780792 - Po zmianie rozdzielczości
11141968 11Mb - Przed imagedestroy
1525056 - Po wykonaniu imagedestroy

I tak mnie nie satysfakcjonuje taka wielkość zajmowanej pamięci - prawie 1,5 MB. Stosując [/u]unset($zmienna) zajmowana pamięć się tylko powiększała. Dziwne bo za pomocą tej funkcji usuwa się zmienna z pamięci. Ale może koledzy macie inne doświadczenia - proszę o testy i przykłady jak zrobić aby wyczyścić bufor poniżej 1 MB?

Ten post edytował smarcz 27.02.2007, 00:34:24
Go to the top of the page
+Quote Post
siemakuba
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 1 112
Pomógł: 20
Dołączył: 10.04.2005

Ostrzeżenie: (0%)
-----


nie wiem czy to coś pomoże, ale wydaje mi się, że nie musisz zapisywać plików z kompresją ustawioną na 100. Przy zmniejszeniu kompresji do 80-90 (przetestuj) nie zauważysz różnicy w jakości pliku, a jego rozmiar spadnie znacząco - co z kolei powinno mieć wpływ na ilość danych w buforze - właśnie w tym miejscu jest tam największa ilość danych.

pozdr.
Go to the top of the page
+Quote Post
smarcz
post
Post #6





Grupa: Zarejestrowani
Postów: 80
Pomógł: 0
Dołączył: 12.05.2005

Ostrzeżenie: (0%)
-----


Tak więc po kolejnym dniu prób - stwierdzam - zmiana kompresji -> znikomy efekt (ale zawsze coś) Jeszcze dziś robiłem testy i co dziwnego odkryłem - bawiłem się z dodawaniem plików jpg z aparatu cyfrowego - niektóre pliki o pojemności powyżej 1 MB prawie 2 MB załączały się przez formularz bez problemu mieszcząc się w dozwolonym buforze 20 MB. Owszem w trakcie wczytywania ImageCreateFrom?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ($plik); pamięć bufora skacze do ponad 15 MB ale pliki przechodzą bez problemu. Co ciekawe dołączałem pliki o mniejszej rozdzielczości - np.: 300 Kb - także jpg - i takie pliki w trakcie obróbki ImageCreateFrom?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ($plik); przekraczały znacząco zajętość bufora 20 MB. Dlaczego?

Moje pytanie - jak określić przed wczytaniem do ImageCreateFrom?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ($plik); ile plik może potrzebować pamięci na taką operację? Szukałem w manualu opisu ile ta bibloteka GD potrzebuje pamięci do przetworzenia 1 pixela obrazka i nie znalazłem. Może macie jakieś doświadczenia z takim zagadnieniem?

Lub inaczej jak stworzyć dla takiego formularza obsługę błędów aby nie pojawiał się komunikat Fatal error i przerywał działanie skryptu - tylko ładnie wcześniej użytkownika poinformować że dodawany plik nie spełnia wymagań?

Może to tędy droga - aby wcześniej wywalić błąd a nie przerywać działania skryptu co jest nieporządane w trakcie zapisu wyników do bazy danych MySQL

Z góry dzięki za wszelkie podpowiedzi. Jakieś gotowe skrypty - możecie pisać na maila smarcz@interia.pl
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 04:15