views:

465

answers:

8

I want to create a gallery of pictures for my website and upload those pictures from the administration panel of the website. I am going to show all pictures in a page with a very small size, and one place I will separate for each picture to show the selected picture (from small ones) with big size.

I know two ways of doing that:

  1. I create 2 pictures for uploading from administration panel, one big and one small with a fixed size. So the big one I will load in the separate big space. And small will be shown in the small places. So the administrator of the site should CREATE 2 pics.

  2. The second way I know is to use the GD library of PHP to be able to upload only the big picture, and in each place a PHP function will resize the big picture and get the 2 sizes that I need for the gallery.

The first method's disadvantage is, that the user of the site should use Photoshop or some other tool before uploading. Let’s agree that this is not a pleasant thing for the site user.

The second approach is not good either, as GD resizes the picture by lowering quality. And that loss is inadmissible because it is too much.

What is a way that does that resize operation while maintaining close to the original picture quality?

Or what is another approach that is better that these two?

+6  A: 

GD doesn't lose quality any more than Photoshop. Just make sure you are using imagecopyresampled() and NOT imagecopyresized() as that does not do any kind of resampling. Then save the resulting image in high enough quality; for JPEG's, that's around 80.

Then do a similar resize in Photoshop and you'll see there's not much difference. You can also use GD to sharpen your thumbnails, that'll give them a little extra crispness.

EDIT

I made a tool to compare different resize methods, try it out and see for yourself what is the best method: http://www.ulmanen.fi/stuff/downsample/

Tatu Ulmanen
I use this method and the JPG compression at 80 works well.
Jessedc
I don't agree, that GD doesn't lose quality. Even Microsoft Picture Manager is processing pictures better than GD, even if I programm with imagecopyresampled() with 100% quality.
Narek
@Narek: I also don't think GD loses quality, what I've noticed is a slightly change in color variation. Either you stick to that or use ImageMagik (not sure if the image loses quality, but most people say not) or you just ask your uploaders to use Photoshop and upload 3 separate images. There is no golden solution here.
Alix Axel
+, very nice showcase =) bigger pictures would be nice though, also this image is quite nice to see small differences http://upload.wikimedia.org/wikipedia/commons/c/ce/Quality_comparison_jpg_vs_saveforweb.jpg
Alix Axel
@Alix, the point was to show the differences (or lack of) between downsizing algorithms, that's the reason for small images.
Tatu Ulmanen
+1  A: 

How about using the quality argument of imagejpeg when outputting your image?

Dominic Rodger
+2  A: 

Use the following function like this:

Image('/path/to/original.image', '1/1', '150*', './thumb.jpg'); // thumb, width = 150 px
Image('/path/to/original.image', null, '600*', './full.jpg'); // full, width = 600 px

You can specify the crop ratio via the second argument (w/h) if you wish, you can also specify the width and/or height of the resized image via the third argument (w*h).

function Image($source, $crop = null, $scale = null, $destination = null)
{
    $source = @ImageCreateFromString(@file_get_contents($source));

    if (is_resource($source) === true)
    {
     $size = array(ImageSX($source), ImageSY($source));

     if (isset($crop) === true)
     {
      $crop = array_filter(explode('/', $crop), 'is_numeric');

      if (count($crop) == 2)
      {
       $crop = array($size[0] / $size[1], $crop[0] / $crop[1]);

       if ($crop[0] > $crop[1])
       {
        $size[0] = $size[1] * $crop[1];
       }

       else if ($crop[0] < $crop[1])
       {
        $size[1] = $size[0] / $crop[1];
       }

       $crop = array(ImageSX($source) - $size[0], ImageSY($source) - $size[1]);
      }

      else
      {
       $crop = array(0, 0);
      }
     }

     else
     {
      $crop = array(0, 0);
     }

     if (isset($scale) === true)
     {
      $scale = array_filter(explode('*', $scale), 'is_numeric');

      if (count($scale) >= 1)
      {
       if (empty($scale[0]) === true)
       {
        $scale[0] = $scale[1] * $size[0] / $size[1];
       }

       else if (empty($scale[1]) === true)
       {
        $scale[1] = $scale[0] * $size[1] / $size[0];
       }
      }

      else
      {
       $scale = array($size[0], $size[1]);
      }
     }

     else
     {
      $scale = array($size[0], $size[1]);
     }

     $result = ImageCreateTrueColor($scale[0], $scale[1]);

     if (is_resource($result) === true)
     {
      ImageFill($result, 0, 0, IMG_COLOR_TRANSPARENT);
      ImageSaveAlpha($result, true);
      ImageAlphaBlending($result, true);

      if (ImageCopyResampled($result, $source, 0, 0, $crop[0] / 2, $crop[1] / 2, $scale[0], $scale[1], $size[0], $size[1]) === true)
      {
       ImageConvolution($result, array(array(-1, -1, -1), array(-1, 16, -1), array(-1, -1, -1)), 8, 0);
       ImageJPEG($result, $destination, 90);
      }
     }
    }

    return false;
}

The image is automatically enhanced (sharpened) and saved as a JPEG with high quality.

Enjoy!

Alix Axel
+2  A: 

You can use ImageMagick instead of GD to get probably better results. I'm not sure what level of integration with your website you need but I suggest checking the open source Gallery project before you start coding.

Maciek Sawicki
+2  A: 

Why not use phpThumb()?

  • You only need to generate src-links for your image tags.
  • Automatic cache.
  • Offers a lot of options to manipulate images. See the demo page.
  • Uses ImageMagick and as fallback GD, that you do not have to care about (but you can).
  • Nearly everything can be configured. See: phpThumb.config.php.
Hippo
phpThumb is pretty good, you can also easily save a copy of the transformation in a cache so you don't have to do the resizing on each load
Tom
A: 

I would use one file upload and then use ImageMagick to create the thumbnail on the server (http://www.imagemagick.org/script/index.php)

+1  A: 

I use this simple shell script, which needs convert from ImageMagick:

#!/bin/sh

W=256
T="Some recent photos"

cat <<EOF
<HTML>
<HEAD>
<TITLE>$T</TITLE>
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY STYLE="font-family: sans-serif">
<H1>$T</H1>
Click on the photos to enlarge<P>
EOF

for i
do
convert -resize $W "$i" "T$i"
cat <<EOF
<A HREF="$i"><IMG SRC="T$i" WIDTH=$W></A>
EOF
done

cat <<EOF
</BODY></HTML>
EOF
lhf
i would rather use the API http://php.net/manual/en/book.imagick.php
Gregory Pakosz
A: 

If you're not picky about where the images are stored, you could use the Flickr PHP API. Since flickr provides the images in a variety of sizes, it leaves you with making the layout for the gallery.

Check out http://phpflickr.com/

I've used this for a project and was surprised at how easy it was. You can basically do every operation through that API, and you can do it for several users too, so you're going to save yourself and others lots of time. And not to mention space!-)

Tor Valamo