2012-11-23 39 views
9

Tôi đã không tìm cách tìm tài liệu chi tiết các giới hạn liên quan đến Phần tử Canvas Html5 như kích cỡ tệp hình ảnh lớn nhất mà nó có thể tải ... Lý do tôi hỏi là tôi đã cố gắng đổi kích thước hình ảnh kích thước khác nhau, từ 50kb đến 2,0mb thông qua ctx.scale(), nhưng nó đã được horribly không phù hợp trong đó cho cùng một hình ảnh đôi khi ctx.drawImage() sẽ thành công và thời gian khác không thành công (không thành công là không có quy mô lại hình ảnh xuất hiện trong canvas).Html5 Canvas Limitations

Tôi cũng đã đặt console.log(base64) để theo dõi kết quả của var base64 = canvas.toDataURL() và nhận thấy rằng khi thay đổi kích thước thành công base64 đã thay đổi kích thước sẽ là chuỗi dài như mong đợi và khi không thay đổi kích thước chuỗi sẽ vẫn xuất hiện tương đối ngắn hình ảnh.

Điều này có liên quan đến giới hạn bộ nhớ và các chuỗi không thành công được bao quanh không? Nếu vậy, giới hạn bộ nhớ được áp đặt trên phần tử canvas là gì?

+0

Xin lỗi vì bất kỳ lỗi nào trong bài đăng và vui lòng sửa tôi vì tôi là người đăng mới cho trang web này. –

Trả lời

8

Đầu tiên:
Giới hạn cứng sẽ phụ thuộc vào trình duyệt, không phải API canvas.
Ngay cả khi đó, các trình duyệt luôn cố gắng để cải thiện hiệu suất của, vì vậy con số đó sẽ luôn thay đổi.
Nhưng với WebGL và Canvas đang được sử dụng để tạo trò chơi, kết quả inlases/sprite atlases là HUGE .jpg/.png tệp.
Rất có thể hình ảnh của bạn nhỏ hơn và tôi thường sử dụng hình ảnh 4MB/5MB/16MB trong canvas để trình diễn.
Một hình ảnh lớn (hoặc hàng chục bức ảnh) có thể làm hỏng tab, nếu nó đủ lớn, nhưng cho đến lúc đó, canvas không thực sự phàn nàn với tôi.

Thứ hai:
Có giới hạn về bảo mật.
Chỉnh sửa ảnh trong canvas đi xuống với trình duyệt bạn đang truy cập và liệu tệp có nằm trên cùng tên miền với trang web của bạn hay không.

Thứ ba:
Khi bạn nói rằng "file lớn không làm việc, nhưng họ làm đôi ..."
... mà dẫn tôi để tin rằng phương pháp tải ảnh của bạn bị lỗi.

Nếu bạn làm điều gì đó như thế này:

var canvas = document.createElement("canvas"), 
    context = canvas.getContext("2d"), 
    img = new Image(); 

img.src = "//mydomain.com/myimg.png"; 
context.drawImage(img, 0, 0, img.width, img.height); 

... hoặc bất cứ điều gì khác mà không phải là một trong hai sự kiện có trụ sở hoặc callback-based,
sau đó vấn đề của bạn không có gì để làm với canvas và có tất cả mọi thứ để làm với callbacks, và rằng bạn đang cố gắng để vẽ hình ảnh vào vải trước khi hình ảnh được thực hiện tải.

Nếu trình duyệt của bạn đã lưu một bản sao của hình ảnh lớn hoặc nếu một hình ảnh nhỏ chỉ mất một phần nhỏ của một giây để tải xuống, thì không có vấn đề gì.

Nếu bạn thử tải xuống hình ảnh 18MB và vẽ hình ảnh đó vào canvas ngay sau khi bạn đặt url cho hình ảnh, thì bạn sẽ nhận được một màn hình trống, vì nó chưa tải xong.

Thay vào đó, bạn cần phải chờ đợi cho hình ảnh để kết thúc tải, và sau đó vẽ nó vào khung khi nó sẵn sàng.

var canvas = document.createElement("canvas"), 
    context = canvas.getContext("2d"), 
    image = new Image(); 

image.onload = function() { 
    var img = this, 
     width = img.width, 
     height = img.height; 

    canvas.width = width; 
    canvas.height = height; 
    context.drawImage(img, 0, 0, width, height); 

    document.body.appendChild(canvas); 
}; 

image.src = "//mydomain.com/path-to-really-huge-image.png"; 

Bây giờ, nó có thể là hình ảnh 16MP. Sẽ không có gì xảy ra cho đến khi tệp được tải xong.
Sau đó, sự kiện onload kích hoạt và thực hiện phần còn lại của quá trình thiết lập.

Bạn có thể làm cho nó trừu tượng hơn và biến nó thành một chương trình tiện lợi, nhưng có vẻ như đây là phần quan trọng bạn có thể bị thiếu.

+0

Cảm ơn rất nhiều, image.onload là phần cuối cùng của câu đố. Tôi bắt đầu nghi ngờ hình ảnh không được tải đầy đủ, do đó tạo ra một chuỗi base64 rút ngắn khi một trang làm mới sẽ thành công (vì hình ảnh được lưu trữ) nhưng sẽ không khi bộ nhớ cache bị làm trống và hình ảnh lớn phải tải lại. Một lần nữa, cảm ơn rất nhiều vì đã trả lời trực tiếp và súc tích! –