[PHP] Image Bewerken: Allowed memory size exhausted

Pagina: 1
Acties:
  • 849 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MindStorm
  • Registratie: Juli 2002
  • Laatst online: 16-01-2024
Ik heb een script geschreven dat, wanneer een gebruiker een foto/plaatje upload, er direct een thumbnail van wordt gemaakt. Dit wordt gedaan om te zorgen dat dit later niet on-the-fly te hoeven doen aangezien het nogal wat cpu vreet.

Het script werkt prima, de plaatjes worden ook daadwerkelijk geresized en opgeslagen in de correcte map. Dit gaat goed, totdat je daadwerkelijk wat grotere bestanden gaat uploaden, en met grotere bedoel ik dan niet in de bestandsgrootte maar het afbeeldingsformaat.

Wanneer je een plaatje/foto groter dan +/- 1750x2300 probeert te uploaden gaat de upload zelf goed, maar de thumbnail wordt niet gemaakt. De volgende foutmelding verschijnt:

code:
1
Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 1944 bytes) in /home/*******/domains/***************/public_html/beta/services/fileService.php on line 72


Wanneer het plaatje als BMP wordt opgeslagen neemt het 14,4 Mb in. Wat waarschijnlijk gebeurt is het volgende: php heeft een plaatje ingelezen op hoge kwaliteit (de hele 14,4 Mb), en vervolgens maak ik in mn scriptje een nieuwe image aan om te resizen (vermoedelijk dus nogmaals 14,4 Mb). Dit vermoeden heb ik omdat wanneer de webhoster op mijn verzoek (tijdelijk) de memory limit van een phpscript verhoogde van 20M naar 35M. Het script werkte toen namelijk wel.

Ik heb een poging gedaan het script 'kleiner' te maken door ongebruikte variabelen te unset()-en, maar dit mocht niet helpen. Hieronder het stuk code (het is een flinke lap, waarvoor excuus):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    public function createThumb(FileInfo $source) {
        $extensionlength = strlen($source->file_extension); //Just in case, but prolly 3.
        $pathlength = strlen($source->file_path);
        $path_noext = substr($source->file_path, 0, $pathlength - ($extensionlength +1));
        $thumb_pathname = $path_noext . "_thumb.jpg";
        
        //check if width > heigth (ie. image is a rotated photo)
        if($source->file_img_x > $source->file_img_y) {
            $target_heigth = ($source->file_img_y * IMG_THUMBX) / $source->file_img_x;
            $thumb = imagecreatetruecolor(IMG_THUMBX, $target_heigth);
            $dst_w = IMG_THUMBX;
            $dst_h = $target_heigth;
        } else {
            $target_width = ($source->file_img_x * IMG_THUMBY) / $source->file_img_y;
            $thumb = imagecreatetruecolor($target_width, IMG_THUMBY);
            $dst_w = $target_width;
            $dst_h = IMG_THUMBY;
        }

//er kunnen meerdere bestandstypen komen, dus even checken welke precies
        switch($source->file_type) {
            case "image/jpeg": $img = imagecreatefromjpeg($source->file_path); break;
            case "image/png": $img = imagecreatefrompng($source->file_path); break;
            case "image/gif": $img = imagecreatefromgif($source->file_path); break;
        }
        
        imagecopyresampled($thumb, $img, 0, 0, 0, 0, $dst_w, $dst_h, $source->file_img_x, $source->file_img_y);
        imagejpeg($thumb, $thumb_pathname);     
        
        $theFile = new FileInfo();
        $path_parts = pathinfo($thumb_pathname);
        if($imgInfo = getimagesize($thumb_pathname)) {
                $type = $imgInfo['mime'];
                $theFile->file_name = "thumb_". $source->file_name;
                $theFile->file_extension = $path_parts['extension'];
                $theFile->file_path = $thumb_pathname;
                $theFile->file_type = $type;
                $theFile->file_size = $_FILES['thefile']['size'];
                $theFile->file_img_x = round($imgInfo[0]);
                $theFile->file_img_y = round($imgInfo[1]);
                $theFile->file_thumb = "y";
                $theFile->file_thumb_of = $source->file_id;
                fileService::addFile($theFile);
        }
        imagedestroy($thumb);
        imagedestroy($img);
    }
  • Mijn vraag is nu vooral, doe ik iets fout, of kan het beter?
Tot nu toe heb ik gegoogled, gephp.net, verschillende tutorials doorgelezen, en ze doen allemaal ongeveer hetzelfde...

[ Voor 1% gewijzigd door MindStorm op 08-08-2006 22:16 . Reden: leesbaarheid vergroten!? ]


Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-09 08:50

gorgi_19

Kruimeltjes zijn weer op :9

Gokmodus:
This happens because converting a compressed image requires the image to be held in memory, uncompressed, at the original size and new size simultaneously. 10:1 compression is not unusual for JPEG images, so this may require more memory than you might expect.
Oftewel: het moet uncompressed ingelezen worden :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • MindStorm
  • Registratie: Juli 2002
  • Laatst online: 16-01-2024
gorgi_19 schreef op dinsdag 08 augustus 2006 @ 21:52:
Oftewel: het moet uncompressed ingelezen worden :)
Klopt, dat is die 14,4 Mb, en dat gaat ook prima, alleen wanneer ik dan het tweede plaatje (dat dus verkleind moet gaan worden) aanmaak, gaat ie hoogstwaarschijnlijk over de 20M heen...

Acties:
  • 0 Henk 'm!

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

gorgi (en jijzelf ook :P ) slaan de spijker op zijn kop, als vergelijking, op onze webservers hebben we de memorylimiet op 64MB staan in verband met dit soort dingen (en React is ook nogal geheugenintensief).

God, root, what is difference? | Talga Vassternich | IBM zuigt


Acties:
  • 0 Henk 'm!

  • MindStorm
  • Registratie: Juli 2002
  • Laatst online: 16-01-2024
moto-moi schreef op dinsdag 08 augustus 2006 @ 21:56:
gorgi (en jijzelf ook :P ) slaan de spijker op zijn kop, als vergelijking, op onze webservers hebben we de memorylimiet op 64MB staan in verband met dit soort dingen (en React is ook nogal geheugenintensief).
Zijn we daar iig uit =) Maar m'n code klopt dus hoogstwaarschijnlijk?

Dan wordt t dus hopen op goedwillendheid van mn hoster... |:(

Acties:
  • 0 Henk 'm!

  • Twan V
  • Registratie: Oktober 2001
  • Laatst online: 16-09 15:39

Twan V

...en er stralend uitzien

Probeer anders eens ImageMagick, wat bij veel hostingproviders en op veel servers geinstalleerd is.

Volgens mij kun je uitleg vinden op imagemagick.org, maar met een beetje googelen weet je zo meer.
Nadeel is dat je via een shell-commando een plaatje verkleind. Je zou even met je provider moeten overleggen of dat (eventueel in safe-mode) toegestaan is.

Blaat het niet dan schaadt het niet...
Reflex Discoshow - Het beste wat je bruiloft kan overkomen


Acties:
  • 0 Henk 'm!

  • XXfrankieXX
  • Registratie: September 2003
  • Laatst online: 09-09 22:04

XXfrankieXX

Who, me?

Ik weet dat dit een heel oud topic is, maar ik zie graag topics met een concrete oplossing aan het eind (vooral omdat GOT hoog bij Google voorbij komt):

Ik kwam zojuist dit probleem tegen, en dit bleek de oplossing (die geldt voor mijn hosting):
  • Maak in het bestand waarin het script draait een bestand genaamd .htaccess en vul hier het volgende in:
  • php_value memory_limit 64M
Dit zorgt er voor dat het geheugen voor php tijdelijk iets hoger wordt.

Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 12:37

Gonadan

Admin Beeld & Geluid, Harde Waren
Niet tijdelijk. Maar bij elke pagina waarvoor die .htaccess geldt.

Je kunt ook in je script het volgende plaatsen. Dan geldt het alleen voor het betreffende script.
PHP:
1
ini_set('memory_limit', '24M');

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8

Pagina: 1