Afbeeldingen snijden met jQuery

Wanneer gebruikers foto's kunnen uploaden, kan het soms zijn dat deze foto's maar een bepaald maximaal formaat mogen hebben. Maar hoe los je zoiets op? Een uitkomst hierin biedt de jQuery plugin jcrop. Hiermee kan je de gebruiker een foto laten uitsnijden en deze vervolgens met PHP daadwerkelijk verkleinen. In deze tutorial leg ik uit hoe je dit zelf kunt doen.

Demo

Geen zin om het artikel te lezen:

Uploaden

Eerst moet ervoor gezorgd worden dat de eind gebruiker een foto kan uploaden. Dat kan door middel van een vrij standaard formulier, met een kleine aanpassing in de <form> tag. Ook moet er een file element toegevoegd worden om de afbeelding daadwerkelijk te kunnen selecteren. De code ziet er dan zo uit:

  1. <form method="POST" action="upload.php" enctype="multipart/form-data">
  2. <strong>Selecteer uw afbeelding:</strong><br />
  3. <input type="file" name="afbeelding" /><br />
  4. <input type="submit" value="Afbeelding uploaden!" />
  5. </form>

Het resultaat ziet er dan zo uit:

Selecteer uw afbeelding:

Afbeelding tonen

De volgende stap is om de afbeelding te tonen. Omdat deze in meerdere stappen nodig is verplaats ik de afbeelding naar een map vanwaar deze verder aangeroepen kan worden. Deze map moet wel voldoende permissies hebben om hier ook daadwerkelijk bestanden heen te kunnen laten schrijven.

upload.php

  1. // controleren of er een formulier verstuurd is
  2. if($_SERVER['REQUEST_METHOD'] == 'POST') {
  3.         // Kijken of het bestand succesvol is geupload
  4.         if($_FILES['afbeelding']['error'] == 0) {
  5.                 // Het bestand wegschrijven naar een amp
  6.                 move_uploaded_file($_FILES['afbeelding']['tmp_name'], 'images/' . $_FILES['afbeelding']['name']);
  7.                
  8.                 // de afbeelding daadwerkelijk tonen
  9.                 echo '<img src="getimage.php?file=images/' . $_FILES['afbeelding']['name'] . '">';
  10.         }
  11. }

In dit voorbeeld zie je dat ik een aparte pagina gebruik voor het tonen van de afbeelding. Deze getimage.php pagina is relatief eenvoudig en ziet er als volgt uit:

  1. // Het bestand welke opgevraagd moet worden in een variabele zetten
  2. $image = $_GET['file'];
  3. // Informatie verkrijgen van de afbeelding
  4. $imageinfo = getimagesize($image);
  5.  
  6. // Hiermee wordt de browser voor de gek gehouden. Deze denkt namelijk dat hij een plaatje voorgeschoteld krijgt
  7. header('content-type: ' . $imageinfo['mime']);
  8. // De inhoud van de afbeelding ophalen en meteen tonen.
  9. echo file_get_contents($image);

Nu de afbeelding geüpload en getoond wordt, wordt het tijd voor het toevoegen van jQuery!

Selecteren

Het laten selecteren van een gedeelte van de afbeelding kan eenvoudig gedaan worden met behulp van Jcrop (Downloaden). Jcrop biedt zeer veel mogelijkheden, maar de basis is vrij eenvoudig. Na het downloaden moet de Jcrop pluging geactiveerd worden in de browser. Dat kan op de volgende manier:

  1. <link rel="stylesheet" href="css/jquery.Jcrop.css" type="text/css" />
  2. <script type="text/javascript" src="../js/jquery.js"></script>
  3. <script type="text/javascript" src="js/jquery.Jcrop.js"></script>

Nu de Jcrop plugin beschikbaar is kan deze op eenvoudige wijze op de afbeelding geactiveerd worden door dit stukje code:

  1. $('img').Jcrop();

Nu kan er een gedeelte van de afbeelding geselecteerd worden. Maar we zijn er nog niet! Omdat het met jQuery niet mogelijk om een afbeelding daadwerkelijk te verkleinen, moeten de geselecteerde afmetingen naar de server verstuurd worden zodat de afbeelding verkleind kan worden zoals aangegeven. Daarvoor moet er eerst een formulier worden gemaakt waar de afmetingen in geplaatst kunnen worden. Dit formulier ziet er zo uit:

  1. <form method="post" action="afbeelding-snijden.php">
  2.         <input type="hidden" name="x" value="" />
  3.         <input type="hidden" name="y" value="" />
  4.         <input type="hidden" name="w" value="" />
  5.         <input type="hidden" name="h" value="" />
  6.         <input type="hidden" name="image" value="images/<?php echo $_FILES['afbeelding']['name']; ?>" />
  7.         <input type="submit" value="Verklein afbeelding!" />
  8. </form>

Om deze velden in te laten vullen met de geselecteerde afmeting, moet de aanroep van de Jcrop functie enigszins aangepast worden:

  1. $('img').Jcrop({
  2.         onSelect: function (c) {
  3.                 $("input[name=x]").val(c.x);
  4.                 $("input[name=y]").val(c.y);
  5.                 $("input[name=w]").val(c.w);
  6.                 $("input[name=h]").val(c.h);
  7.         }
  8. });

Nu de afmetingen in een formulier geplaatst worden zijn wij bij de laatste stap aangekomen: Het daadwerkelijk verkleinen. Dit wordt door PHP gedaan in combinatie met de GD library.

Verkleinen

De onderstaande code is enkel geschikt voor JPG afbeeldingen. Wil je deze geschikt maken voor bijvoorbeeld GIF, PNG of BMP afbeeldingen dan zal de code enigszins aangepast moeten worden.

  1. $targ_w = $_POST['w'];
  2. $targ_h = $_POST['h'];
  3. $jpeg_quality = 90;
  4.  
  5. $src = $_POST['image'];
  6. $img_r = imagecreatefromjpeg($src);
  7. $dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
  8.  
  9. imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
  10. $targ_w,$targ_h,$_POST['w'],$_POST['h']);
  11.  
  12. header('Content-type: image/jpeg');
  13. imagejpeg($dst_r,null,$jpeg_quality);

Voilá, afbeeldingen kunnen nu op maat gesneden worden. Nu kun je deze afbeelding bijvoorbeeld opslaan, of de afmetingen in de database opslaan zodat de real-time verkleind wordt wanneer deze opgevraagd wordt.

Jcrop opties

Jcrop heeft verschillende opties die de moeite waard zijn. Zo kan er een ratio gezet worden:

  1. $('img').Jcrop({
  2.         aspectRatio: 1
  3. });

Liever een vooraf bepaald ratio opgeven? Dat kan ook:

  1. $('img').Jcrop({
  2.         aspectRatio: 16/9
  3. });

Ook kan er een minimum hoogte gebruikt worden:

  1. $('img').Jcrop({
  2.         minSize: [150, 150]
  3. });

En dan kan ook er ook een maximum hoogte ingesteld worden:

  1. $('img').Jcrop({
  2.         maxSize: [150, 150]
  3. });

Meteen beginnen met een selectie grootte die vooraf bepaald is? Gebruik dan setSelect:

  1. $('img').Jcrop({
  2.         setSelect: [150, 150, 500, 500]
  3. });

Live demo

BijlageGrootte
afbeeldingen-snijden-met-jquery.zip100.4 KB