Este problema surge del hecho de que al cargar archivos de imágenes, el fondo limita el tamaño a 2 MB, pero cuando la cámara se enciende para tomar fotografías, supera los 2 MB cada minuto, para no afectar la experiencia del usuario y los requisitos funcionales. El front-end necesita comprimir el tamaño y luego cargarlo entre bastidores.
Análisis de ideasDespués de buscar mucha información, descubrí que solo el lienzo puede comprimir imágenes.
El principio es aproximadamente el siguiente: 1. Primero convierta el archivo de la imagen en baseURL 2. Cree una etiqueta de imagen para recibir el archivo y obtener el ancho, alto y proporción de la imagen. 3. Cree un lienzo y establezca el tamaño del lienzo. 4. Dibuja el dibujo en el lienzo. 5. Comprima el lienzo y obtenga una nueva URL base. 6. Convierta la URL base nuevamente en un archivo.
función de la premisa Convertir archivo de archivo a base64/*** @param {flujo de archivo binario} archivo * @param {función de devolución de llamada, devolver base64} fn */function changeFileToBaseURL(file,fn){ // Crea un objeto de archivo de lectura var fileReader = new FileReader(); Si el archivo no está definido, devuelve nulo if(file == indefinido) return fn(null); // Lee el archivo, el resultado es fileReader.readAsDataURL(file) de base64 bits; fileReader.onload = function(){ // Lee la base64 var imgBase64Data = this.result;Convertir base64 a flujo de archivos
/** * Convertir base64 a archivo * @param {baseURL} dataurl * @param {nombre de archivo} nombre de archivo * @return {flujo binario de archivo}*/function dataURLtoFile(dataurl, nombre de archivo) { var arr = dataurl.split(' , '), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n } return new File([u8arr], nombre de archivo, {tipo:mime});Método de compresión
/*** imagen comprimida del lienzo* @param {obj de parámetro} param * @param {secuencia binaria de archivo} param.file requerido* @param {tamaño de compresión objetivo} param.targetSize no pasa la asignación inicial -1* @param {salida Ancho de imagen} param.width no pasa el valor de asignación inicial -1 y no pasa la altura para la escala proporcional* @param {nombre de la imagen de salida} param.fileName no pasa la imagen de asignación inicial* @param {grado de la imagen comprimida } param.quality no supera el valor de asignación inicial de 0,92. Rango de valores 0~1* @param {función de devolución de llamada} param.succ requerido */function pressImg(param){ //Si no hay una función de devolución de llamada, no se ejecutará if(param && param.succ){ //Si el archivo no está definido, devuelve nulo if(param.file == undefinido) return param.succ(null); //Adjunte un valor inicial al parámetro param.targetSize = param.hasOwnProperty(targetSize)? param.targetSize: -1; param.width = param.hasOwnProperty(ancho)? param.width: -1; param.fileName = param.hasOwnProperty(fileName)? calidad) ? param.calidad: 0.92; var _this = this; // Obtener el tipo de archivo var fileType = param.file.type; // console.log(fileType) //image/jpeg if(fileType.indexOf(image) == -1){ console.log('Seleccione un archivo de imagen^_^'); return param.succ(null); } // Si el tamaño actual es menor que el tamaño objetivo, genera directamente var size = param.file.size if(param.targetSize > size){ return param.succ(param.file; ); } / / Lea el archivo y el resultado es base64 changeFileToBaseURL(param.file,function(base64){ if(base64){ var image = new Image(); image.src = base64; image.onload = function(){ // Obtener la relación de aspecto var escala = this.width / this.height; // console.log(scale //Crea un lienzo var canvas = document.createElement('canvas'); //Obtener el contexto var context = canvas.getContext('2d'); //Obtener el ancho de la imagen comprimida. Si el ancho es -1, el ancho de la imagen original predeterminado canvas.width = param.width == -1. ancho: param.width; //Obtiene la altura de la imagen comprimida. Si el ancho es -1, la altura de la imagen original predeterminada es canvas.height = param.width == -1? parseInt(param.width / scale); //Dibuja la imagen en el lienzo context.drawImage(image, 0, 0, canvas.width, canvas.height); //Comprime la imagen y obtiene una nueva base64Url var newImageData = canvas. toDataURL(fileType,param.quality); //Convierte base64 en una secuencia de archivos var resultFile = dataURLtoFile(newImageData,param.fileName); //Juzgue si targetSize es limitado y el tamaño de la imagen comprimida es mayor que el tamaño objetivo, aparecerá un error if(param.targetSize != -1 && param.targetSize < resultFile.size ){ console .log (El tamaño de carga de la imagen es demasiado grande, vuelva a cargarla ^_^); param.succ(null }else{); // Devolver flujo de archivo param.succ(resultFile);Uso del método
El tamaño del archivo está en bytes, por lo que debemos convertir el tamaño requerido a bytes. 1 byte es 1 byte es 1B, 1KB = 1024B, 1MB = 1024 * 1024B
<tipo de entrada=id de archivo=fileImg clase=fileImg/>
//Obtener la URL de carga del archivo de imagen$(#fileImg).on('change',function(){ pressImg({ file:this.files[0], targetSize:2 * 1024 * 1024, calidad:0.5, ancho:600 , succ:function(resultFile){ //Si no es nulo, la compresión es exitosa if(resultFile){ //TODO } } })});Resumen del problema Nivel de compresión de imagen
El grado de compresión de la imagen no es fácil de determinar, por lo que puedes probarlo muchas veces y ajustarlo según los requisitos del demandante. Cambiar el tamaño y la resolución de la imagen de destino puede cambiar el grado de compresión de la imagen.
Originalmente quería hacer un proceso recursivo de comprimir imágenes hasta que el tamaño de la imagen cumpliera con las expectativas.Más tarde descubrí
Porque cuando iOS llama a la cámara del sistema para tomar fotografías, ésta gira 90 grados en sentido antihorario. Después de comprimir la imagen y enviarla al fondo, descubrí que la dirección de disparo de la información exif de la imagen se perdió, lo que provocó que las imágenes cargadas por iOS giraran 90 grados en sentido antihorario. Android nunca ha notado este problema.
En la actualidad, existe cierta sospecha de que se perdió cuando base64 se convirtió en un archivo. Se proporcionarán instrucciones adicionales aquí después de la verificación.
@version1.0-2019-8-2-Create "Usar lienzo para comprimir el tamaño de la imagen"
©burning_Yun Qiqi
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.