En este artículo veremos cómo subir imágenes al servidor, cortarlas y redimensionarlas utilizando PHP y AJAX. En un artículo anterior ya vimos cómo subir imágenes y recortarlas utilizando un popup box. Obtuve una gran respuesta por vuestra parte, pero muchos me solicitásteis el volver a publicar el artículo sobre el recorte de imágenes y redimensionamiento sin el popup box ni ventanas modales, para que se puede reproducir fielmente en tabletas y dispositivos móviles.
En este artículo veremos cómo subir imágenes y recortarlas en la misma página sin tener que utilizar una ventana modal. Utilizaremos la librería GD de PHP para redimensionar las imágenes, y el plugin de jQuery, AJAX Form, para subir las imágenes. También le daremos uso al plugin Imgareaselect para cortar la imagen y a PHP para guardar la imagen una vez esté redimensionada y cortada.
Resumiendo, esto será lo que utilicemos:
- Librería jQuery: Librería base para soportar otros plugins de jQuery
- Boostrap: La utilizaremos para crear diseños alucinantes y responsives
- imgareaselect: La utilizaremos para cortar imágenes. Puedes descargarla desde aquí
- Ajax Form: La utilizaremos para subir las imágenes del usuario al servidor. Puedes descargarla desde aquí.
Estos son los archivos que participarán en el tutorial de cortado de imágenes
- index.php: Este fichero es el responsable de crear todo el diseño HTML y mostrar la imagen recortada
- profile.php: Este fichero es el responsable de toda la funcionalidad del lado del servidor, como recortar la imagen y guardarla.
- dist: Es una carpeta. La utilizaremos para albergar todas las librerías.
Subida, cortado y redimensionamiento de imágenes con PHP y AJAX
Paso 1: Antes que nada tenemos que incluir todas las librerías necesarias para que esto funcione, como son las de jQuery y Bootstrap. Introduce el siguiente código dentro de la sección head de tu archivo index.php.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="dist/jquery.imgareaselect.js" type="text/javascript"></script>
<script src="dist/jquery.form.js"></script>
<link rel="stylesheet" href="dist/imgareaselect.css">
Paso 2: Crearemos un div para mostrar la imagen y una opción para modificarla.
<div class="col-sm-2"><img class="img-circle" id="avatar-edit-img" height="128" data-src="default.jpg" data-holder-rendered="true" style="width: 140px; height: 140px;" src="default.jpg"/></div>
<div class="col-sm-10"><a type="button" class="btn btn-primary" id="change-pic">Change Image</a>
</div>
Aquí mostraremos la imagen default.jpg cuando no haya nada como imagen por defecto.
Paso 3: Ahora crearemos el div para subir y recortar la imagen.
<div id="changePic" class="" style="display:none">
<form id="cropimage" method="post" enctype="multipart/form-data" action="profile.php">
<label>Upload your image</label><input type="file" name="photoimg" id="photoimg" />
<input type="hidden" name="hdn-profile-id" id="hdn-profile-id" value="1" />
<input type="hidden" name="hdn-x1-axis" id="hdn-x1-axis" value="" />
<input type="hidden" name="hdn-y1-axis" id="hdn-y1-axis" value="" />
<input type="hidden" name="hdn-x2-axis" value="" id="hdn-x2-axis" />
<input type="hidden" name="hdn-y2-axis" value="" id="hdn-y2-axis" />
<input type="hidden" name="hdn-thumb-width" id="hdn-thumb-width" value="" />
<input type="hidden" name="hdn-thumb-height" id="hdn-thumb-height" value="" />
<input type="hidden" name="action" value="" id="action" />
<input type="hidden" name="image_name" value="" id="image_name" />
<div id='preview-avatar-profile'>
</div>
<div id="thumbs" style="padding:5px; width:600"></div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="btn-crop" class="btn btn-primary">Crop & Save</button>
</div>
</div>
Paso 4: Necesitamos implementar algo de jQuery para mostrar el div del recorte de la imagen cuando se haga clic en el botón change pic
jQuery('#change-pic').live('click', function(e){ e.preventDefault(); jQuery('#changePic').show(); jQuery('#change-pic').hide(); });
Paso 5: Ahora utilizaremos el plugin de jQuery, AJAX Form para hacer submit del formulario y mostrar la imagen para el proceso de recorte en una ventana modal de bootstrap.
jQuery('#photoimg').live('change', function() { jQuery("#preview-avatar-profile").html(''); jQuery("#preview-avatar-profile").html('Uploading....'); jQuery("#cropimage").ajaxForm( { target: '#preview-avatar-profile', success: function() { jQuery('img#photo').imgAreaSelect({ aspectRatio: '1:1', onSelectEnd: getSizes, }); } }).submit(); });
Puedes definir los parámetros de la imagen dentro de la función callback que está en success.
Paso 6: Ahora cortamos la imagen y llamamos al método save de AJAX para guardar la imagen en el disco duro del usuario.
//call on crop iamge button jQuery('#btn-crop').live('click', function(e){ e.preventDefault(); params = { targetUrl: 'profiles/saveAvatarTmp/', action: 'profiles_controller_saveAvatarTmp', x_axis: jQuery('#hdn-x1-axis').val(), y_axis : jQuery('#hdn-y1-axis').val(), x2_axis: jQuery('#hdn-x2-axis').val(), y2_axis : jQuery('#hdn-y2-axis').val(), thumb_width : jQuery('#hdn-thumb-width').val(), thumb_height:jQuery('#hdn-thumb-height').val() }; saveCropImage(params); }); //make ajax request to PHP for save image function saveCropImage(params) { jQuery.ajax({ url: siteurl + params['targetUrl'], cache: false, dataType: "html", data: { action: params['action'], id: jQuery('#hdn-profile-id').val(), t: 'ajax', w1:params['thumb_width'], x1:params['x_axis'], h1:params['thumb_height'], y1:params['y_axis'], x2:params['x2_axis'], y2:params['y2_axis'] }, type: 'Post', // async:false, success: function (response) { jQuery('#changePic').hide(); jQuery('#change-pic').show(); jQuery(".imgareaselect-border1,.imgareaselect-border2,.imgareaselect-border3,.imgareaselect-border4,.imgareaselect-border2,.imgareaselect-outer").css('display', 'none'); jQuery("#avatar-edit-img").attr('src', response); jQuery("#preview-avatar-profile").html(''); jQuery("#photoimg").val(''); AlertManager.showNotification('Image cropped!', 'Click Save Profile button to save image.', 'success'); }, error: function (xhr, ajaxOptions, thrownError) { alert('status Code:' + xhr.status + 'Error Message :' + thrownError); } }); }
Paso 7: Definimos el método controlador/acción en profile.php
/*********************************************************************
Purpose : update image.
Parameters : null
Returns : integer
***********************************************************************/
public function changeAvatar() {
global $current_user;
$loggedInId = $current_user->ID;
$post = isset($_POST) ? $_POST: array();
$max_width = "500";
$userId = isset($post['hdn-profile-id']) ? intval($post['hdn-profile-id']) : 0;
$path = get_theme_root(). 'imagesuploadstmp';
$valid_formats = array("jpg", "png", "gif", "bmp","jpeg");
$name = $_FILES['photoimg']['name'];
$size = $_FILES['photoimg']['size'];
if(strlen($name))
{
list($txt, $ext) = explode(".", $name);
if(in_array($ext,$valid_formats))
{
if($size<(1024*1024)) // Image size max 1 MB
{
$actual_image_name = 'avatar' .'_'.$userId .'.'.$ext;
$filePath = $path .'/'.$actual_image_name;
$tmp = $_FILES['photoimg']['tmp_name'];
if(move_uploaded_file($tmp, $filePath))
{
$width = $this->getWidth($filePath);
$height = $this->getHeight($filePath);
//Scale the image if it is greater than the width set above
if ($width > $max_width){
$scale = $max_width/$width;
$uploaded = $this->resizeImage($filePath,$width,$height,$scale);
}else{
$scale = 1;
$uploaded = $this->resizeImage($filePath,$width,$height,$scale);
}
$res = $this->Profile->saveAvatar(array(
'userId' => isset($userId) ? intval($userId) : 0,
'avatar' => isset($actual_image_name) ? $actual_image_name : '',
));
//mysql_query("UPDATE users SET profile_image='$actual_image_name' WHERE uid='$session_id'");
echo "<img id='photo' class='' src='".getCustomAvatar($userId, true).'?'.time()."' class='preview'/>";
}
else
echo "failed";
}
else
echo "Image file size max 1 MB";
}
else
echo "Invalid file format..";
}
else
echo "Please select image..!";
exit;
}
Paso 8: Guardamos la ruta de la imagen dentro de la base de datos
/********************************************************************* Purpose : save avatar. Parameters : $options Returns : true/false ***********************************************************************/ function saveAvatar($options){ //update sql }
Fuente: phpflow.com