1° HTML con el form para upload, la div msg para retorno de data y img para la imagen
<body>
<div class="cenefa" style="border:none;"> <!-- inicio cenefa -->
<div style="float:left; margin-left:40px;">
<img src="../imagenes/logo_cenefa.png" width="139" height="75" alt="Iqsystems-home" >
</div>
</div> <!-- fin cenefa -->
<div class="cierre"></div>
<div style="margin: 0 auto; padding:15px;">
<div style="margin:0 auto;margin-bottom: 20px;">
SUBIR IMAGEN JPG CREAR THUMB Y ROTARLO SI ES NECESARIO
</div>
<!-- Bloque caso 1-->
<div style="text-align:center; margin:20px; padding:5px; border: solid 1px #333 ">
<div style="text-align:left;">
<div style="text-align:center;font-size:14px;margin-bottom:15px; ">
SUBIR LA IMAGEN Y CREAR EL THUMBNAIL
</div>
<form method="post" id="formulario" enctype="multipart/form-data">
<div style="margin-bottom:10px; ">Subir la imagen(tamaño maximo:500K valida solo .heic .jpg .gif .png ) </div>
<div>
<input name="archivo" type="file" accept=".heic,.jpg,.jpeg,.png,.gif" style="height:24px; ">
<span id="esperando" style="visibility: hidden; ">
<img src="esperando.gif" style="width: 16px; height:16px;" />
</span>
</div>
<div style="margin-bottom:10px; margin-top:20px; text-align:center;" id="msg"> </div>
</form>
</div>
<div style="margin-bottom:10px; margin-top:20px; text-align:left;" >
<img src="" style="max-width: 300px;" id="subida" />
<span style="padding:10px" id="flechita"></span>
<img src="" id="thumb" />
</div>
</div>
</div>
</body>
2° JAVASCRIPT (JQUERY) con AJAX
<head>
<script>
$(document).ready(function(){
//Subir un .heic convertirlo a jpg, grabarlo y mostrar imagen y data.
$("input[name='archivo']").on("change", function(){ //es la forma de indicar el FILE
var formData = new FormData($("#formulario")[0]); //carga todos los datos del form en array
var ruta = "tec-php-thumb-procesar.php"; //ruta del script uploader
$("#esperando").css("visibility", "visible"); // esperando.....
$.ajax({
url: ruta,
type: "POST",
data: formData, //datos del form declarado
contentType: false,
processData: false,
success: function(dato){
var datos = JSON.parse(dato); // metemos la devolución AJAX en array (data no puede ser JSON)
if(datos.devolucion!= ''){
var texto = 'Nombre: ' + datos.devolucion + '</br>';
texto += 'Dimensiones: '+ datos.ancho + ' x ' + datos.alto + '</br>';
texto += 'Tamaño: '+ datos.peso + '</br>';
texto += 'Fecha: '+ datos.fecha + '</br>';
texto += '*****************************************************</br>';
texto += 'Nombre thumbnail: _' + datos.devolucion + '</br>';
texto += 'Dimensiones thumbnail: '+ datos.anchominiatura + ' x ' + datos.altominiatura + '</br>';
texto += 'Tamaño: '+ datos.pesominiatura + '</br>';
$("#msg").html(texto); //mando los datos del archivo subido y cambiado
$("#esperando").css("visibility", "hidden"); //desaparece esperando....
$("#subida").attr('src', datos.ruta); //le cambio el src al de la imagen subida
$("#flechita").html(' => '); //aparece una flechita
$("#thumb").attr('src', datos.rutaminiatura); //le cambio el src al de la imagen subida
}else{
$("#esperando").css("visibility", "hidden"); //desaparece esperando....
$("#msg").html('Ha ocurrido un error'); //envío el mensaje de error
}
} //fin success
}); // fin ajax
}); // fin on change
}); // fin ready.
</script>
</head>
3° SCRIPT (PHP)
<?php
// funciones necesarias********************************
date_default_timezone_set('America/Argentina/Buenos_Aires');
function nombrecopia($arch){
$a= getdate(); //array asociativo con los elementos de fecha y hora
$me = str_pad($a['mon'],2,'0',STR_PAD_LEFT); // mes ajustado a dos dígitos padeado con ceros a la izq.
$di = str_pad($a['mday'],2,'0',STR_PAD_LEFT); //idem día
$ho = str_pad($a['hours'],2,'0',STR_PAD_LEFT); //idem hora
$mi = str_pad($a['minutes'],2,'0',STR_PAD_LEFT); //idem minutos
$se = str_pad($a['seconds'],2,'0',STR_PAD_LEFT); //idem segundos
return substr($arch, 0, strrpos($arch,'.')) . "-copia-" . $a['year']. "-". $me."-".$di."_".$ho.$mi.$se. substr($arch, strrpos($arch,'.'));
}
function extension($archivo){
return substr($archivo,strrpos($archivo,'.') + 1); //busca último punto +1 y corta de ahí hasta final
}
function raiz($archivo){
return substr($archivo,0,strrpos($archivo,'.')); // corta desde principio hasta último punto
}
function peso($peso){
if ($peso<1024){
return $peso . " B";
}else if($peso>1024 && $peso<1048576){
return round($peso/1024,1 ). " KB";
}else if($peso>1048576 && $peso<1073741824){
return round($peso/1048576,2 ). " MB";
}else{
return round($peso/1073741824,2 ). " GB";
}
}
// FIN funciones*************************************
$maxancho=100; // ancho max del thumbnail
$maxalto=100; // alto max del thumbnail
if (isset($_FILES["archivo"])){ // si viene algo del form
$file = $_FILES["archivo"]; //cargo en $file la info
$nombre = $file["name"]; //nombre original subido
$ruta_provisional = $file["tmp_name"]; //ruta temporaria en server
$ruta = "img-dropzone/"; // ruta final
$extension = extension($nombre); // extensión del archivo
$raiznombre = raiz($nombre); // raiz del nombre del archivo
$im = new Imagick(); //creo el objeto imagick
$im->readImage($ruta_provisional); // grabo la imagen desde el temporal
if ($extension =='HEIC' || $extension=='heic'){ // si es heic
$im->setImageFormat('jpeg'); // le cambio el formato a jpg
$nombre = $raiznombre . '.jpg'; // le cambio la extensión en el nombre
}
if(file_exists($ruta. $nombre)){ //si ya hay imagen con ese nombre se lo cambio
$nombre = nombrecopia($nombre);
}
$ruta_final= $ruta. $nombre;
$im->writeImage($ruta_final); // grabo en el disco la imagen grande
// proceso para el thumbnail
$ancho = $im->getImageWidth(); //obtengo ancho de la grande
$alto = $im->getImageHeight(); //obtengo alto de la grande
$x_prop = $maxancho / $ancho; //proporción de reduccion ancho
$y_prop = $maxalto / $alto; //proporción de reduccion alto
if (($x_prop * $alto) < $maxalto){ //si reduzco altura y quedo chico
$ancho_final = ceil($y_prop * $ancho); //entonces reduzco ancho
$alto_final = $maxalto; // y dejo el alto (menor al max)
}else{
$alto_final = ceil($x_prop * $alto); // si no reduzco alto
$ancho_final = $maxancho; // y dejo ancho (menor al max)
}
$im->thumbnailImage($ancho_final,$alto_final); // creo el thumbnail
//************* si está rotada (jpg) la original corrijo la orientación del thumbnail.**************************
$ext=extension($nombre);
if($ext=='jpg'|| $ext=='JPG' || $ext=='jpeg' || $ext=='JPEG'){
$exif = exif_read_data($ruta_final); //leo los datos exif de la grande grabada
if (array_key_exists('Orientation', $exif)) { // si existe la clave orientación
$orientacion = $exif['Orientation']; // leo la orientación
if (!empty($orientacion)) { //si hay datos de orientación roto el thumbnail
$fondo = new ImagickPixel('#00000000'); // color de fondo para las rotaciones no enteras pi/2
switch ($orientacion) {
case 3:
$im->rotateImage($fondo, 180);
break;
case 6:
$im->rotateImage($fondo, 90);
break;
case 8:
$im->rotateImage($fondo, 270);
break;
}
} //fin not empty $orientacion
} //fin array_key_exists
} // fin if jpg
$rutathumb = $ruta.'_'. $nombre;
$im->writeImage($rutathumb); // grabo en el disco el thumbnail con _nombre
$im->clear(); // destruyo objeto y libero memoria
$peso = peso(filesize($ruta_final)); //tamaño en Bytes peso(paso a string con B, KB, MB, GB)
$pesothumb = peso(filesize($rutathumb)); //tamaño en Bytes del thumb
$fecha = date("d/m/Y", filectime($ruta_final)); // fecha de última modificación de inode (o sea upload en este caso)
$resultado=array("devolucion"=>$nombre,"ruta"=>$ruta_final,"ancho"=>$ancho,"alto"=>$alto,"peso"=>$peso,"anchominiatura"=>$ancho_final,"altominiatura"=>$alto_final,"fecha"=>$fecha,"tipo"=>$ext,"rutaminiatura"=>$rutathumb,"pesominiatura"=>$pesothumb);
echo(json_encode($resultado));
}// fin if (is set) si viene algo del form
?>