[英]Does javascript canvas drawimage work on iPhones?
我有一個 web 頁面,它從輸入加載圖像並調整大小和旋轉,因此它始終是縱向的並將其顯示到屏幕上。 這適用於桌面瀏覽器和 android,但不適用於我朋友的 iPhone。
function showImage(){
var input = document.getElementById("card");
var filesToUpload = input.files;
var file = filesToUpload[0];
var img = document.createElement("img");
var reader = new FileReader();
reader.onload = function (e) {
img.src = e.target.result
}
reader.onloadend = function () {
var canvas = document.createElement("canvas");
var width = img.width;
var height = img.height;
var ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var imgloc = document.getElementById("cardloc");
imgloc.appendChild(canvas);
}
reader.readAsDataURL(file);}
<input id="card" name="card" type="file" accept="image/*" capture/>
<button type=button id="chooseButton" name="chooseButton" onclick="showImage()">
Choose A card
</button>
<div id="cardloc"></div>
這是代碼的縮減版本,沒有調整大小和旋轉來演示問題。 工作時,您可以看到 img.src 填充了編碼圖像,並且 canvas.toDataURL() 也返回編碼圖像。 在 iphone 上 img.src 已填充,但 canvas.toDataURL() 未填充,只有 6 個字符長表示未加載圖像。
我完全沒有想法,有人可以幫忙嗎?
確實如此(盡管我手頭沒有 iPhone)。
這里的問題是加載圖像是一個異步任務(它與 JavaScript 執行並行執行),即使源是數據:URL,並且您無法繪制尚未加載到 ZFCC75150C72DA8DCF61 上的圖像.
現在為什么它可以在某些瀏覽器上運行? 因為您實際上也在異步執行繪圖部分,但是在一個不相關的事件中。
底層有點復雜,但基本上 FileReader 總是在讀取 Blob 時觸發兩個不同的事件: onerror和onloadended或onload和onloadend , onloadend在前一個事件之后立即觸發。
在這里,您在onload
事件中設置<img>
的src
,此時瀏覽器將開始加載圖像。 由於它來自數據:URL,它沒有太多事情要做(沒有網絡請求),所以當第二個事件( onloadend )觸發時,它實際上可能已經加載了圖像,因此可以繪制它canvas。
但是,這實際上是一種僥幸。
處理它的正確方法是等待圖像的onload
事件。
reader.onload = function (e) {
img.onload = function () {
var canvas = document.createElement("canvas");
var width = img.width;
var height = img.height;
var ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var imgloc = document.getElementById("cardloc");
imgloc.appendChild(canvas);
};
img.src = e.target.result
}
reader.readAsDataURL(file);
但是你在這里甚至不需要 FileReader,你最好使用一個blob:URL ,它只是一個指向磁盤上文件的指針,從而避免浪費 memory,並且還避免了一級回調地獄:
img.onload = function () {
var canvas = document.createElement("canvas");
var width = img.width;
var height = img.height;
var ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var imgloc = document.getElementById("cardloc");
imgloc.appendChild(canvas);
}
img.src = URL.createObjectURL(file);
Ps:既然你說你也做裁剪,如果你在這個修復后仍然對 Safari 有問題,那么我邀請你閱讀這個關於這個瀏覽器中實際錯誤的Q/A (我不能確定你正面臨你在這里給我們的東西)。
謝謝您的幫助。
我知道異步調用。 我只是沒有發現 img 也有 onload 。
img onload 發生在閱讀器 onloadend 之后,在 android 上這不是問題,但在 iPhone 上卻是。
所以我只需要將 reader.onloaded 更改為 img.onload 就可以了。
非常感謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.