He estado tratando de volver a implementar un cargador de imágenes HTML5 como el del sitio Mozilla Hacks , pero eso funciona con los navegadores WebKit. Parte de la tarea es extraer un archivo de imagen del canvas
objeto y agregarlo a un objeto FormData para cargarlo.
El problema es que, si bien canvas
tiene la toDataURL
función de devolver una representación del archivo de imagen, el objeto FormData solo acepta objetos File o Blob de File API .
La solución de Mozilla utilizó la siguiente función exclusiva de Firefox en canvas
:
var file = canvas.mozGetAsFile("foo.png");
... que no está disponible en los navegadores WebKit. La mejor solución que se me ocurre es encontrar alguna forma de convertir un URI de datos en un objeto de archivo, que pensé que podría ser parte de la API de archivo, pero por mi vida no puedo encontrar algo para hacer eso.
¿Es posible? Si no, ¿alguna alternativa?
Gracias.
fuente
Respuestas:
Después de jugar con algunas cosas, me las arreglé para resolver esto.
En primer lugar, esto convertirá un dataURI en un Blob:
A partir de ahí, es fácil agregar los datos a un formulario para que se carguen como un archivo:
fuente
POST
oPUT
para S3?ArrayBuffer
, que luego se escribe en laBlobBuilder
instancia.var file = new File( [blob], 'canvasImage.jpg', { type: 'image/jpeg' } ); fd.append("canvasImage", file);
BlobBuilder y ArrayBuffer ahora están en desuso, aquí está el código del comentario superior actualizado con Blob constructor:
fuente
array=[]; array.length=binary.length;
...array[i]=bina
... etc. Entonces la matriz está preasignada. Ahorra un push () al tener que extender la matriz en cada iteración, y estamos procesando posiblemente millones de elementos (= bytes) aquí, por lo que es importante.Este funciona en iOS y Safari.
Debe usar la solución ArrayBuffer de Stoive, pero no puede usar BlobBuilder, como indica vava720, así que aquí está el mashup de ambos.
fuente
Firefox tiene los métodos canvas.toBlob () y canvas.mozGetAsFile () .
Pero otros navegadores no lo hacen.
Podemos obtener dataurl del lienzo y luego convertir dataurl a objeto blob.
Aquí está mi
dataURLtoBlob()
función. Es muy corto.Use esta función con FormData para manejar su lienzo o dataurl.
Por ejemplo:
Además, puede crear un
HTMLCanvasElement.prototype.toBlob
método para el navegador no gecko engine.Ahora
canvas.toBlob()
funciona para todos los navegadores modernos, no solo Firefox. Por ejemplo:fuente
Mi forma preferida es canvas.toBlob ()
Pero de todos modos, aquí hay otra forma de convertir base64 en un blob usando fetch ^^,
fuente
XMLHttpRequest
ya que la url de datos es solo una url, puede usar ajax para recuperar ese recurso y tiene una opción para decidir si lo desea como blob, arraybuffer o textoblob:
ydata:
no son universalmente compatibles con todas las implementaciones de recuperación. Utilizamos este enfoque, ya que sabemos que solo trataremos con navegadores móviles (WebKit), pero Edge, por ejemplo, no lo admite itt: developer.mozilla.org/en-US/docs/Web/API/…Gracias a @Stoive y @ vava720 combiné los dos de esta manera, evitando usar BlobBuilder y ArrayBuffer en desuso
fuente
El estándar en evolución parece ser canvas.toBlob () no canvas.getAsFile () como Mozilla se atrevió a adivinar.
Todavía no veo ningún navegador que lo admita :(
Gracias por este gran hilo!
Además, cualquiera que intente la respuesta aceptada debe tener cuidado con BlobBuilder ya que encuentro que el soporte es limitado (y espacio de nombres):
¿Estaba utilizando el polyfill de otra biblioteca para BlobBuilder?
fuente
canvas.toBlob()
, parece mucho más apropiado quegetAsFile
.BlobBuilder
parece estar en desuso a favor deBlob
se puede usar sin el intento de captura.
Gracias a check_ca. Buen trabajo.
fuente
La respuesta original de Stoive se puede corregir fácilmente cambiando la última línea para acomodar Blob:
fuente
Aquí hay una versión ES6 de la respuesta de Stoive :
Uso:
fuente
¡Gracias! @steovi para esta solución.
He agregado soporte a la versión ES6 y he cambiado de unescape a dataURI (unescape está en desuso).
fuente
hazlo simple: D
fuente
toDataURL te da una cadena y puedes poner esa cadena en una entrada oculta.
fuente
<input type=hidden value="data:..." />
que haría), quiero cargar los datos del archivo (como lo que<input type="file" />
hace, excepto que no puedes establecer lavalue
propiedad en estos).Tuve exactamente el mismo problema que Ravinder Payal, y encontré la respuesta. Prueba esto:
fuente
window.open(canvas.toDataURL("image/jpeg"))