PHP Help

Dear lazy web:

How do I make PHP not run out of memory when doing thumbnails of large images? I’ve got this code:

                        $href = $path . "/" . $file;
			$tn_file = "thumbnail-" . $file;
			$orig_file = $full_path . "/" . $file;

			/* generate thumbnail if it does not exist */
			if (file_exists ($tn_file) == false) {
				$im = @imagecreatefromjpeg ($orig_file);
				if (!$im) {
				        $im = @imagecreatefrompng ($orig_file);
					if (!$im)
						continue;
					$is_png = 1;
				} else
					$is_png = 0;

				if (imagesx ($im) < imagesy ($im)) {
					$new_width = round (imagesx ($im) / (imagesy ($im) / 240));
					$new_height = 240;
				} else {
					$new_width = 240;
					$new_height = round (imagesy ($im) / (imagesx ($im) / 240));
				}
				
				$copy_im = imagecreatetruecolor ($new_width, $new_height);
				imagecopyresampled ($copy_im, $im, 0, 0, 0, 0,
					$new_width, $new_height, imagesx ($im), imagesy ($im));
				if (is_png == 1)
				        imagepng ($copy_im, $tn_file);
				else
				        imagejpeg ($copy_im, $tn_file);

				imagedestroy ($copy_im);
				imagedestroy ($im);
			}

			//$get_url = "/images/thumbnail-" . $file;
			$get_url = $tn_file;

It works great for most of my images (as you can see here), but it doesn't for big images (2592x1944 pixels, like this one).

I've been trying all the solutions mentioned in this page, but none seems to work for me :-( I am assuming it's an out-of-memory problem, but could it be something else?

18 Responses to “PHP Help”

  1. Zash says:

    You could hope that most images of that size has a embedded EXIF thumbnail. I have a thumbnailer script that does just that on my own temporary-image-host thingy, which looks like this: .

  2. Zash says:

    Your wordpress ate my link! Here it is again without less/greater than around: http://pastebin.com/f65162d8c

    The important part is http://php.net/exif_thumbnail and stuff around row #57

  3. diegoe says:

    Usa el módulo de imagemagick, con lo que viene en PHP el problema no siempre es la memoria, a veces simplemente decide fallar porque no le agrada algo de la cabecera del jpeg, o cosas así.
    Alguna vez me tocó procesar toneladas de imágenes suministradas por usuarios con PHP, nos pasamos 2 semanas intentando mil soluciones hasta que simplemente cogimos el módulo de ImageMagick (en PECL si mal no recuerdo).

  4. Robbert says:

    php_value memory_limit 64M

    The default is very low (8MB I think), so better set it to a higher value.

  5. Robbert says:

    I forgot to mention that you have to put that in your .htaccess.

  6. alex says:

    ini_set(‘memory_limit’, 80 * 1024 * 1024);
    set_time_limit(0);

    works for me

  7. Matt Mossholder says:

    The silly, obvious answer is “Shell out” :)

  8. Giasone says:

    What kind of error do you have? How much is memory limit parameter in your php.ini file? Probably the value it’s too lower.

  9. erik snoeijs says:

    Above advise with the ini_set memory limit will probably work if that’s the problem. But I would strongly recommend not putting it in your htaccess file but calling it when you actually need the extra memory. (i.e. right before loading the image into memory)

    Otherwise each php instance will reserve that much memory and that’s not what you want.

  10. erik snoeijs says:

    Hmm, just wanted to add. If your on shared hosting and you are restricted so that you can’t increase the memory limit, you might be able to cheat a little bit.

    This depends on what tools are installed but if something like imagemagick is installed (or happens to live static compiled in your directory) you could call “exec” and resize the image via some command line utilities. This would probably circumvent any memory restrictions that were put on php.

    Although by doing that you might break some written/unwritten rules with your hoster ;)

    Also, glossing over your code, having a sort of fail, try again approach to ‘what type of image’ is this, is pretty bad. When using “getimagesize” get get an array back which among others includes the mime type, on basis of which you can call the correct create*.

  11. Sean says:

    Best recommendation I can give you, after professionally working on very large PHP sites for the past few years, is to just avoid PHP like the plaque and use a language designed by people who don’t have their heads lodged up their asses.

    I would avoid messing with memory limits because there’s no guarantee that a future host will even allow you to change it. If your host allows you to set that limit in the .htaccess that already means that they’re using mod_php and hence are morons (mod_php forces them to use an ancient, low-performance Apache MPM and isn’t even as fast as using php+fastcgi with that same MPM), and a future host you might move to hopefully has the good sense to not use mod_php and hence make any PHP configuration changes in .htaccess totally invalid.

    You can set the memory limit up at runtime in some server configurations, but not all.

    Shelling out works, but is slow, and you have to make sure you’re very careful not to introduce a gaping security hole into your site software.

    I’ve found that using a dedicated image server is a huge benefit for throughput to the site, and you can pretty quickly develop a simple internal-use-only image upload utility for said server, and write the tiny bit of software that needs in Ruby or Python or Java or C# or C or assembler or Brainfuck or some other clearly-better-than-PHP language.

  12. i made a php module that wraps a few of the GdkPixbuf routines. it’s a lot faster than the built-in routines and uses less memory. give it a try if you like…

    http://mike.yi.org/cgi-bin/viewvc.cgi/?root=php-pixbuf

  13. You could use the ImageMagick extension: http://ca2.php.net/imagick

    We use it to successfully process hundreds of thousands of photos ranging from a megabyte to 100 megabytes. You’ll also need to do
    ini_set(‘memory_limit’, -1); set_time_limit(0); or something similar.

  14. Sharninder says:

    Why not just use imagemagick for this ? If you have to use built-in functions then you’ll have to increase the memory for php processes.

  15. Niko says:

    Or you use the imagick extension: http://pecl.php.net/package/imagick

  16. James says:

    Don’t do this sort of thing when the agent hits the URL for the thumbnail. At best it’s going to be slow. Have a script that watches your images and creates thumbs when it finds them – that’s faster for the user since the thumbs are cached and you don’t have to do crazy shit with your php install.

  17. rodrigo says:

    Thanks to all for the suggestions and the quick responses! At the end, what I’m doing is generating them locally before uploading them to the server. I don’t have full access to the hosting server, so I can’t really install stuff there. It seems to work great locally, and as James suggested, it’s quicker to have it this way.

    Thanks again to all!

  18. mike says:

    Hello..i want to ask how can i create a calender appointment use the php script ? have any idea or script ..i hearing from you?