[PHP] resizen van 5MB afbeelding met 32MB geheugen

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

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo allemaal,

Voor een ander probleem zit ik met het volgende. Ik heb het volgende stukje code om afbeeldingen in het formaat JPG te verkleinen, echter kan ik afbeeldingen die groter zijn dan 2MB niet resizen door te weinig geheugen.

Graag zou ik willen weten of het mogelijk is (technisch gezien) om een afbeelding van maximaal 5MB kan thumbnailen met PHP op een server die 32MB toewijst aan deze actie.

Mijn code is als volgt:
PHP:
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
48
49
50
51
52
53
54
// is the orginal file still existing.
$im = @imagecreatefromjpeg($file);

// file is opend for editing
if ($im)
{
    // set up thumbnail sizes
    $im_width  = imageSX($im);
    $im_height = imageSY($im);

    if ($size >= $im_width && $size >= $im_height)
    {
        display($file);
    }
    else
    {
        $new_size = cSize($im_width, $im_height, $size);

        // create new image.
        $new_im = ImageCreateTrueColor($new_size['width'],
                                       $new_size['height']);

        // thumbnail the image.
        ImageCopyResized($new_im,
                         $im,
                         0,
                         0,
                         0,
                         0,
                         $new_size['width'],
                         $new_size['height'],
                         $im_width,
                         $im_height);


        if (isSet($_GET['thumb']) && $_GET['thumb'] == "500")
        {
            ImageJpeg($new_im,
                      $file,
                      75);
        }

        // make image as jpeg.
        ImageJpeg($new_im,
                  $fileThumb,
                  75);

        // remove build settings. (cache)
        ImageDestroy($im);
        ImageDestroy($new_im);

        display($fileThumb);
    }
}


Heeft iemand hier een oplossing voor?

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Je kan max_file_exec_time en max_file_mem (oid) verhogen via PHP, maar de server moet dat toelaten!
PHP:
1
ini_set("memory_limit","32M");


Zet dat bovenaan, en verander 32 in whatever? ;)

[ Voor 33% gewijzigd door Snake op 03-09-2007 19:44 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Kalief
  • Registratie: Maart 2005
  • Laatst online: 16:37
Als ik het jpg formaat goed begrijp verloopt diens compressie horizontaal. Je zou dan een plaatje in meerdere horizontale stroken kunnen knippen, die apart resizen en weer aan elkaar plakken.

Niemand wordt Kalief in plaats van de Kalief!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@Snake; Een verandering in memory limit is geen optie.
@Kalief; dat is inderdaad een optie, maar hoe wil je dit gaan berekenen?

Acties:
  • 0 Henk 'm!

  • snooze
  • Registratie: September 2002
  • Laatst online: 27-07 16:28

snooze

kinda busy atm.

ik zou zeggen per regel gewoon

weet iemand nog een leuke signature?


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Gewoon opknippen in stuks van max 2MB? Is toch niet zo moeilijk. Je weet toch hoe groot 1 pixel is..

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

JPG comprimeert in blokjes van 8x8 pixels, niet in individuele pixels. Maar in principe is het verhaal hetzelfde. Aangezien je minimale compressie-output 1 blokje van 8x8 pixels beslaat, moet je dus die blokjes inlezen die uiteindelijk in dat 8x8 blokje terecht komen. Alleen kan GD je daar waarschijnlijk niet bij helpen

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@.oisyn, dan zit er niets anders op dan gewoon blokken te resizen en aan elkaar te plakken...

Acties:
  • 0 Henk 'm!

  • ATS
  • Registratie: September 2001
  • Laatst online: 18-09 15:14

ATS

Hoewel het een leuke academische oefening is om dit voor elkaar te krijgen (en als dat de bedoeling van de TS is, prima!), maar ik zou hier mijn tijd niet aan verspillen als ik eerlijk ben. Ik zou zeggen: ga eens praten met de beheerder van je server, of zoek desnoods een andere server als je er met de eerste niet uit komt. Tenslotte kan je ook het resizen nog off-site doen indien nodig. Dat kan wel eens goedkoper uitpakken dan uren kostbare tijd investeren in iets dat je in drie regels code opgelost wil hebben.

[ Voor 0% gewijzigd door ATS op 04-09-2007 09:33 . Reden: typo ]

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • writser
  • Registratie: Mei 2000
  • Laatst online: 19-09 20:58
ATS schreef op dinsdag 04 september 2007 @ 08:24:
Hoewel het een leuke academische oefening is om dit voor elkaar te krijgen (en als dat de bedoeling van de TS is, prima!), maar ik zou hier mijn tijd niet aan verspillen als ik eerlijk ben. Ik zou zeggen: ga eens praten met de beheerder van je server, of zoek desnoods een andere server als je er met de eerst niet uit komt. Tenslotte kan je ook het resizen nog off-site doen indien nodig. Dat kan wel eens goedkoper uitpakken dan uren kostbare tijd investeren in iets dat je in drie regels code opgelost wil hebben.
100% mee eens.

Onvoorstelbaar!


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
GD is sowieso enorm geheugen intensief.
Heb je niet de mogelijkheid om Imagemagick te gebruiken? Dan heb je uberhaupt geen probleem van PHP's memory-limit (vermits je hem command-line gebruikt, niet de PHP extensie)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@ATS: hoezo academische oefening? is dit dan in jou opinie zo moeilijk? lijkt mij niet echt heel erg moeilijk

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Rocket sience is het nu ook weer niet, maar een fourier transformatie (of in het geval van jpeg, cosinus transformatie om van het complexe deel af te zijn) is nu eenmaal niet stof die op de middelbare school behandeld wordt. Je zult je jpeg stukje voor stukje uit moeten pakken, herschalen en weer in moeten pakken. Dat is lang zo triviaal niet als je denkt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • ATS
  • Registratie: September 2001
  • Laatst online: 18-09 15:14

ATS

Verwijderd schreef op woensdag 05 september 2007 @ 07:38:
@ATS: hoezo academische oefening? is dit dan in jou opinie zo moeilijk? lijkt mij niet echt heel erg moeilijk
Moeilijk... moeilijk is misschien niet het goede woord. Maar ik denk dat je aardig wat "corner cases" gaat tegenkomen als je dit wil gaan doen door in stroken te gaan opdelen of zoiets. Dat zorgt voor veel werk. Als je een echt geoptimaliseerde oplossing met een zo laag mogelijk geheugengebruik in PHP wil maken dan lijkt me dat inderdaad best wel lastig en een "leuke academische oefening"1.
Als je Imagemagick kan gebruiken ben je natuurlijk ook snel klaar, maar anders zou ik er mijn tijd niet mee verdoen. Maargoed, als iemand een oplossing kan laten zien in een overzichtelijke hoeveelheid code ben ik best benieuwd.

edit:
1 En dat is dan nog buiten het feit dat je dit soort dingen (jpeg de- en encoden en resizen) helemaal niet in PHP wil doen. Daar is PHP gewoon niet voor geschikt. Dit soort dingen bouw je in een taal waarin je veel beter kan optimaliseren: C of zo. PHP is leuk voor het scripten van sites, maar veel verder moet je er m.i. niet mee gaan. Ik kan me dan ook niet voorstellen dat je zoiets in PHP performant gaat krijgen.

[ Voor 21% gewijzigd door ATS op 05-09-2007 11:13 ]

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • Adion
  • Registratie: Januari 2001
  • Laatst online: 15:35
Ik wilde laatst eens bekijken of ik een lossless jpg-crop programma kon maken, en heb daarvoor toen de jpeg-specificatie opgezocht. In totaal is de specificatie toch wel vrij groot, en is het inderdaad niet zo triviaal om snel even een jpeg-decoder + encoder op maat te schrijven.
De fourier-analyse en de Huffman-compressie zijn misschien op zich wat moeilijk, maar daar kan je waarschijnlijk wel gewoon bestaande code voor zoeken (die je misschien wel nog naar php moet omzetten).
Maar om gewoon het geheel in elkaar te doen passen is denk ik inderdaad toch wel een hoop werk, dus kijken of er toch geen andere mogelijkheden zijn kan misschien toch wel nuttig zijn.

VirtualDJ 2024 - Fast Image Resizer - Instagram


Acties:
  • 0 Henk 'm!

Verwijderd

ATS schreef op woensdag 05 september 2007 @ 09:44:
En dat is dan nog buiten het feit dat je dit soort dingen (jpeg de- en encoden en resizen) helemaal niet in PHP wil doen. Daar is PHP gewoon niet voor geschikt. Dit soort dingen bouw je in een taal waarin je veel beter kan optimaliseren: C of zo. PHP is leuk voor het scripten van sites, maar veel verder moet je er m.i. niet mee gaan. Ik kan me dan ook niet voorstellen dat je zoiets in PHP performant gaat krijgen.
Ik heb een paar jaar geleden wat gespeeld met het decodeer-deel van deze jpeg library. Daar zat een test-progje (geschreven in C) bij dat een jpeg-encoded image kon scannen op een per-8-scanlines manier, waarbij dus het geheugengebruik binnen de perken blijft. Je kon de lib zelfs zo compileren, dat het zelfs onder good-old MSDOS met zijn 640 KB limiet nog kon werken (heb dit zelf niet uitgeprobeerd). De decodeer-performance was redelijk, maar niet supersnel. Pluspunt is de ondersteuning voor de diverse varianten binnen de jpeg/jfif std (baseline/progressive, restart, etc).

Je zou kunnen overwegen om met deze lib een apart progje te schrijven, en dat dan vanuit PHP aan te roepen (dwz als dat laatste kan, ik ben een absolute PHP-n00b).

De API biedt overigens ook de mogelijkheid om JFIF files (dat zijn de bekende .jpg files, die dus een jpeg image bevatten) te scannen per SOS-segment, zodat je bijvoorbeeld bij progressive images kunt besluiten om de refine-segmenten te skippen. Dit komt de performance zeker ten goede. Maar ja, dan ben je natuurlijk wel wat meer tijd kwijt aan het uitzoeken hoe e.e.a. werkt.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Als je al de mogelijkheid hebt een externe tool aan te roepen bestaat het probleem niet meer. Het geheugen van dergelijke tools telt niet mee voor je php script (afaik). Dan zou je immers ook gewoon magick aan kunnen roepen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

slightly off-topic, voor de geïnteresseerden:
Adion schreef op woensdag 05 september 2007 @ 10:42:
In totaal is de specificatie toch wel vrij groot, en is het inderdaad niet zo triviaal om snel even een jpeg-decoder + encoder op maat te schrijven.
Het schrijven van een recht-toe, recht-aan decoder is meer vervelend dan moeilijk door de vele details, maar vereist imho geen graad in rocket-science. De wiskunde ervoor en de opbouw van een JFIF file kun je bijvoorbeeld opzoeken in dit boek, waarin ook wat optimalisatietruuks voor de IDCT beschreven worden. Het schrijven van een decoder die ook hard loopt, is echter wel degelijk een niet-triviale klus.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Er is helaas geen mogelijkheid tot het aanroepen van externe tools, ben bang dat ik gewoon een limiet op de grootte van het te uploaden afbeelding moet zetten... want om zelf nu een JPG parser te schrijven voor PHP..... kost mij ook heeeeel veel tijd :)

Acties:
  • 0 Henk 'm!

  • Oxiounking
  • Registratie: Oktober 2006
  • Niet online
probeer de image te laden (imagecreatefromjpeg), dan met een for loop in stukjes pakken en verkleinen(imagecopyresized), en in een nieuw plaatje plakken (imagecreatetruecolor), en dan weer om te zetten naar jpeg of png (imagejpeg/imagepng).

het besparende zit erin dat je nu maar een klein stukje per keer resized. en als ik het me goed herriner, zet GD de images om naar een ander formaat, voordat hij ze bewerkt, maar dat weet ik niet zeker.

Anders moet je zelf een verklein functie schrijven, niet zo moeilijk, alleen het gemiddelde nemen van de kleuren van de pixels.

Als je de image zelf niet kan laden, is het een ander verhaal.

[ Voor 6% gewijzigd door Oxiounking op 08-09-2007 09:19 ]

Pagina: 1