Próbowałem ponownie wdrożyć program do przesyłania obrazów HTML5, taki jak ten na stronie Mozilla Hacks , ale działa on z przeglądarkami WebKit. Częścią zadania jest wyodrębnienie pliku obrazu z canvas
obiektu i dołączenie go do obiektu FormData w celu przesłania.
Problem polega na tym, że chociaż canvas
ma toDataURL
funkcję zwracania reprezentacji pliku obrazu, obiekt FormData akceptuje tylko obiekty File lub Blob z interfejsu API File .
W rozwiązaniu Mozilla zastosowano następującą funkcję tylko dla Firefoksa canvas
:
var file = canvas.mozGetAsFile("foo.png");
... który nie jest dostępny w przeglądarkach WebKit. Najlepszym rozwiązaniem, jakie mogłem wymyślić, było znalezienie sposobu na konwersję identyfikatora URI danych na obiekt File, który moim zdaniem może być częścią interfejsu API File, ale przez całe życie nie mogę znaleźć czegoś takiego.
Czy to możliwe? Jeśli nie, jakieś alternatywy?
Dzięki.
źródło
Odpowiedzi:
Po zabawie z kilkoma rzeczami sam to odkryłem.
Przede wszystkim spowoduje to konwersję dataURI na obiekt Blob:
Stamtąd dołączanie danych do formularza, który zostanie przesłany jako plik, jest łatwe:
źródło
POST
lubPUT
do S3?ArrayBuffer
, która jest następnie zapisywana wBlobBuilder
instancji.var file = new File( [blob], 'canvasImage.jpg', { type: 'image/jpeg' } ); fd.append("canvasImage", file);
BlobBuilder i ArrayBuffer są teraz przestarzałe, oto kod najwyższego komentarza zaktualizowany o konstruktor Blob:
źródło
array=[]; array.length=binary.length;
...array[i]=bina
... itd. Tak więc tablica jest wstępnie przydzielona. Oszczędza to push () konieczności rozszerzania tablicy przy każdej iteracji, a my przetwarzamy tutaj prawdopodobnie miliony elementów (= bajtów), więc to ma znaczenie.Ten działa w iOS i Safari.
Musisz użyć rozwiązania ArrayBuffer firmy Stoive, ale nie możesz używać BlobBuilder, jak wskazuje vava720, więc oto połączenie obu.
źródło
Firefox ma metody canvas.toBlob () i canvas.mozGetAsFile () .
Ale inne przeglądarki nie.
Możemy pobrać dataurl z kanwy, a następnie przekonwertować dataurl na obiekt blob.
Oto moja
dataURLtoBlob()
funkcja. Jest bardzo krótki.Użyj tej funkcji z FormData do obsługi obszaru roboczego lub bazy danych.
Na przykład:
Możesz także utworzyć
HTMLCanvasElement.prototype.toBlob
metodę dla przeglądarki silnika innego niż gecko.Teraz
canvas.toBlob()
działa dla wszystkich nowoczesnych przeglądarek nie tylko Firefox. Na przykład:źródło
Mój preferowany sposób to canvas.toBlob ()
Ale w każdym razie tutaj jest jeszcze inny sposób przekonwertowania base64 na obiekt blob przy użyciu funkcji pobierania ^^,
źródło
XMLHttpRequest
ponieważ adres danych jest tylko adresem URL. Możesz użyć ajax, aby pobrać ten zasób i masz możliwość samodzielnego wyboru, czy chcesz go jako blob, bufor bufora czy tekstblob:
idata:
nie są one powszechnie obsługiwane przez wszystkie implementacje pobierania. Używamy tego podejścia, ponieważ wiemy, że będziemy zajmować się tylko przeglądarkami mobilnymi (WebKit), ale na przykład Edge nie obsługuje go: developer.mozilla.org/en-US/docs/Web/API/…Dzięki @Stoive i @ vava720 połączyłem je w ten sposób, unikając używania przestarzałych BlobBuilder i ArrayBuffer
źródło
Ewoluujący standard wygląda na canvas.toBlob (), a nie canvas.getAsFile (), jak zgadywał Mozilla.
Nie widzę jeszcze żadnej przeglądarki, która to obsługuje :(
Dzięki za ten świetny wątek!
Ponadto każdy, kto próbuje zaakceptować odpowiedź, powinien zachować ostrożność w przypadku BlobBuilder, ponieważ uważam, że wsparcie jest ograniczone (i przestrzeń nazw):
Czy używałeś wypełniania innej biblioteki dla BlobBuilder?
źródło
canvas.toBlob()
- wydaje się to bardziej odpowiednie niżgetAsFile
.BlobBuilder
wydają się być przestarzałe na korzyśćBlob
może być użyty bez try catch.
Podziękowania dla check_ca. Świetna robota.
źródło
Oryginalną odpowiedź Stoive'a można łatwo naprawić, zmieniając ostatnią linię, aby pomieścić Blob:
źródło
Oto wersja odpowiedzi Stoive na ES6 :
Stosowanie:
źródło
Dzięki! @steovi dla tego rozwiązania.
Dodałem obsługę wersji ES6 i zmieniłem z unescape na dataURI (unescape jest przestarzały).
źródło
uprość: D
źródło
toDataURL daje ci ciąg, który możesz umieścić w ukrytym wejściu.
źródło
<input type=hidden value="data:..." />
by zrobiłoby), chcę przesłać dane pliku (podobnie jak to<input type="file" />
, co robi, z wyjątkiem tego , że nie wolno ci ustawiać dla nichvalue
właściwości).Miałem dokładnie taki sam problem jak Ravinder Payal i znalazłem odpowiedź. Spróbuj tego:
źródło
window.open(canvas.toDataURL("image/jpeg"))