tamaƱo reducir que lienzo archivo javascript html5 file-upload html5-canvas

javascript - reducir - que es un lienzo en photoshop



Redimensionar la imagen antes de cargarla: convertir el lienzo en un objeto de Archivo (3)

Aquí está el fragmento de código que estoy usando ahora para cargar varias imágenes usando la API de archivos HTML5:

/** * @param {FileList} files */ upload: function(files){ nfiles = files.length; for (var i = 0; i < nfiles; i++) { /** @var file File **/ var file = files[i]; var xhr = new XMLHttpRequest(); xhr.open("POST", settings.post_upload, true); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.upload.filenumb = i; xhr.filenumb = i; xhr.upload.filename = file.name; var nef = new FormData(); nef.append("folder", settings.folder); nef.append("file_element", settings.file_elem); nef.append("udata", settings.user_data); nef.append(settings.file_elem, file); xhr.send(nef); } }

Me gustaría cambiar el tamaño de las imágenes antes de cargarlas utilizando un objeto de lienzo, pero como no tengo experiencia con esto, no estoy seguro de cómo actualizar el código usando técnicas, por ejemplo, la que se describe aquí: HTML5 Pre-redimensiona las imágenes antes de cargarlas

canvas.toDataURL("image/png"); devolverá una cadena codificada. Pero necesito publicar el objeto File .

Editar

¿Cómo escribiría (razonablemente) la función de navegador cruzado para la mayoría de los navegadores modernos para cambiar el tamaño del archivo antes de cargarlo, manejar jpg, png y gifs con transparencia:

/** * @param {File} file * @param int max_width * @param int max_height * @param float compression_ratio * @returns File */ function resize(file, max_width, max_height, compression_ratio){}


Intenta algo como esto:

function resize(file, max_width, max_height, compression_ratio, imageEncoding){ var fileLoader = new FileReader(), canvas = document.createElement(''canvas''), context = null, imageObj = new Image(), blob = null; //create a hidden canvas object we can use to create the new resized image data canvas.id = "hiddenCanvas"; canvas.width = max_width; canvas.height = max_height; canvas.style.visibility = "hidden"; document.body.appendChild(canvas); //get the context to use context = canvas.getContext(''2d''); // check for an image then //trigger the file loader to get the data from the image if (file.type.match(''image.*'')) { fileLoader.readAsDataURL(file); } else { alert(''File is not an image''); } // setup the file loader onload function // once the file loader has the data it passes it to the // image object which, once the image has loaded, // triggers the images onload function fileLoader.onload = function() { var data = this.result; imageObj.src = data; }; fileLoader.onabort = function() { alert("The upload was aborted."); }; fileLoader.onerror = function() { alert("An error occured while reading the file."); }; // set up the images onload function which clears the hidden canvas context, // draws the new image then gets the blob data from it imageObj.onload = function() { // Check for empty images if(this.width == 0 || this.height == 0){ alert(''Image is empty''); } else { context.clearRect(0,0,max_width,max_height); context.drawImage(imageObj, 0, 0, this.width, this.height, 0, 0, max_width, max_height); //dataURItoBlob function available here: // http://.com/questions/12168909/blob-from-dataurl // add '')'' at the end of this function SO dont allow to update it without a 6 character edit blob = dataURItoBlob(canvas.toDataURL(imageEncoding)); //pass this blob to your upload function upload(blob); } }; imageObj.onabort = function() { alert("Image load was aborted."); }; imageObj.onerror = function() { alert("An error occured while loading image."); }; }

Tenga en cuenta:

Trabajar con cargadores de archivos y cargar imágenes significa que hay algunos retrasos y, por lo tanto, la función es asíncrona, por lo que tratar de simplemente devolver los datos de blob no funciona. Debe esperar a que se produzca la carga antes de poder utilizar los datos cargados y disparar una llamada a su función de carga para CADA archivo.

También el cargador de archivos puede tener algunos problemas de compatibilidad con el navegador, pero no creo que esto sea posible de ninguna otra manera del lado del cliente.


Puedes llamar a toBlob en el elemento <canvas> . Esto devolverá un Blob , que es la interfaz principal del File . Luego puede enviar este objeto a su servidor a través de XHR2.


Tamaño de imagen del lado del cliente

Opción 1. Usar la biblioteca de Pica ( https://github.com/nodeca/pica )

Opción 2. Utilice el siguiente script personalizado ( http://jsfiddle.net/cL3hapL4/2/ )

var file = document.getElementById(''imageUpload''); var mime = "image/jpeg"; var max_width = 100; var max_height = 100; var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); var img = new Image(); img.onload = function () { // Clear canvas, and resize image ctx.clearRect(0, 0, max_width, max_height); ctx.drawImage(img, 0, 0, img.width, img.height, // size of image 0, 0, max_width, max_height // size of canvas ); // Get image from canvas as a dataURI, and convert to a blob object var dataURI = canvas.toDataUrl(mime); // Note: This function can be replaced with canvas.toBlob(), // once supported by browsers. // --- var image_blob = (function () { var binary = atob(dataURI.split('','')[1]); var array = []; for(var i = 0; i < binary.length; i++) { array.push(binary.charCodeAt(i)); } return new Blob([new Uint8Array(array)], {type: mime}); })(); // --- // Attach blob-object (contains our image) to form object var form = new Form(); form.append("image", image_blob); // Send AJAX request with multi-part data var xhr = new XMLHttpRequest(); xhr.open(''POST'', ''/route'', true); xhr.send(form); // jQuery version //$.ajax({ // type: "POST", // url: "/route", // data: form, // processData: false, // contentType: false //}) //.done(function (response) { // console.log(response); //}); }; img.src = URL.createObjectURL(file);