Estou tentando reimplementar um carregador de imagens HTML5 como o do site Mozilla Hacks , mas que funciona com os navegadores WebKit. Parte da tarefa é extrair um arquivo de imagem do canvas
objeto e anexá-lo a um objeto FormData para upload.
O problema é que, embora canvas
tenha a toDataURL
função de retornar uma representação do arquivo de imagem, o objeto FormData aceita apenas objetos File ou Blob da API de arquivos .
A solução Mozilla usou a seguinte função somente do Firefox em canvas
:
var file = canvas.mozGetAsFile("foo.png");
... que não está disponível nos navegadores WebKit. A melhor solução que eu consegui pensar é encontrar uma maneira de converter um URI de dados em um objeto File, que eu pensei que poderia fazer parte da API de arquivos, mas não consigo encontrar uma coisa para isso.
É possível? Caso contrário, existem alternativas?
Obrigado.
fonte
Respostas:
Depois de brincar com algumas coisas, eu mesmo consegui descobrir isso.
Primeiro de tudo, isso converterá um dataURI em um Blob:
A partir daí, é fácil anexar os dados a um formulário para que sejam enviados como um arquivo:
fonte
POST
ouPUT
a S3?ArrayBuffer
, que é gravado naBlobBuilder
instância.var file = new File( [blob], 'canvasImage.jpg', { type: 'image/jpeg' } ); fd.append("canvasImage", file);
BlobBuilder e ArrayBuffer agora estão obsoletos, eis o código do comentário principal atualizado com o construtor Blob:
fonte
array=[]; array.length=binary.length;
...array[i]=bina
... etc. Portanto, o array é pré-alocado. Isso evita que push () precise estender a matriz a cada iteração, e estamos processando possivelmente milhões de itens (= bytes) aqui, por isso importa.Este funciona no iOS e Safari.
Você precisa usar a solução ArrayBuffer da Stoive, mas não pode usar o BlobBuilder, como indica o vava720, então aqui está o mashup de ambos.
fonte
O Firefox possui os métodos canvas.toBlob () e canvas.mozGetAsFile () .
Mas outros navegadores não.
Podemos obter o dataurl da tela e, em seguida, converter o dataurl em objeto de blob.
Aqui está a minha
dataURLtoBlob()
função. É muito curto.Use esta função com FormData para manipular sua tela ou dataurl.
Por exemplo:
Além disso, você pode criar um
HTMLCanvasElement.prototype.toBlob
método para um navegador que não seja um mecanismo de lagartixa.Agora
canvas.toBlob()
funciona para todos os navegadores modernos, não apenas para o Firefox. Por exemplo:fonte
Minha maneira preferida é canvas.toBlob ()
Mas, de qualquer forma, aqui está outra maneira de converter base64 em um blob usando fetch ^^,
fonte
XMLHttpRequest
uma vez url de dados é apenas um URL, você pode usar ajax para buscar esse recurso e você obteve-se uma opção para decidir se você quer que ele como blob, ArrayBuffer ou textoblob:
edata:
não é universalmente suportado por todas as implementações de busca. Usamos essa abordagem, pois sabemos que lidaremos apenas com navegadores móveis (WebKit), mas o Edge, por exemplo, não oferece suporte a ela: developer.mozilla.org/en-US/docs/Web/API/…Graças a @Stoive e @ vava720, combinei os dois dessa maneira, evitando usar o BlobBuilder e o ArrayBuffer obsoletos
fonte
O padrão em evolução parece ser canvas.toBlob () e não canvas.getAsFile (), pois a Mozilla corria o risco de adivinhar.
Ainda não vejo nenhum navegador que suporte :(
Obrigado por este ótimo tópico!
Além disso, qualquer pessoa que tente a resposta aceita deve ter cuidado com o BlobBuilder, pois estou achando o suporte limitado (e com espaço para nome):
Você estava usando o polyfill de outra biblioteca para o BlobBuilder?
fonte
canvas.toBlob()
- parece muito mais apropriado do quegetAsFile
.BlobBuilder
parece estar obsoleto em favor deBlob
pode ser usado sem a tentativa de captura.
Obrigado a check_ca. Ótimo trabalho.
fonte
A resposta original de Stoive é facilmente corrigível alterando a última linha para acomodar o Blob:
fonte
Aqui está uma versão ES6 da resposta do Stoive :
Uso:
fonte
Obrigado! @steovi para esta solução.
Eu adicionei suporte à versão ES6 e mudei do unescape para dataURI (o unescape está obsoleto).
fonte
simplifique: D
fonte
toDataURL fornece uma string e você pode colocá-la em uma entrada oculta.
fonte
<input type=hidden value="data:..." />
faria), quero fazer upload dos dados do arquivo (como o que<input type="file" />
faz, exceto que você não tem permissão para definir avalue
propriedade).Eu tive exatamente o mesmo problema que Ravinder Payal e encontrei a resposta. Tente o seguinte:
fonte
window.open(canvas.toDataURL("image/jpeg"))