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
