2013-01-01 31 views
6

Tôi nhận thấy có vấn đề lạ với getImageData; độ trong suốt của hình ảnh dường như bị bỏ qua khi dữ liệu hình ảnh được tìm nạp.Độ trong suốt bị mất với getImageData - HTML5 2d Bối cảnh

Vì bất kỳ hình ảnh nào cần phải được vẽ lên canvas trước khi dữ liệu hình ảnh của nó có thể thu được, tôi cho rằng đây là vấn đề với canvas được đề cập bị mờ. Nhưng tôi đã sai, kể từ khi sử dụng các canvas như một đối số trong drawImage duy trì tính minh bạch.

Đây là cách tôi tải hình ảnh;

var load_image = function(name, url, holder, callback) { 
    var img = new Image(); 
    img.src = url; 

    img.addEventListener('load', function(e) { 
     var canvas = make_canvas(e.target.width, e.target.height); 
     var ctx = canvas.getContext('2d'); 

     ctx.clearRect(0, 0, canvas.width, canvas.height); 
     ctx.drawImage(e.target, 0, 0); 

     holder[name] = {canvas: canvas, ctx: ctx}; 

     delete e.target; 

     callback.call(); 
    }, false); 
}; 

Các callback chỉ đơn giản là chức năng vẽ, mà gọi draw_image để vẽ hình ảnh.

Phiên bản thông thường;

var draw_image = function(ctx, img, sx, sy, w, h, dx, dy) { 
    ctx.drawImage(img.canvas, sx, sy, w, h, dx, dy, w, h); 
}; 

Đơn giản chỉ cần lấy canvas làm đối số cho drawImage và kết quả là nhằm mục đích duy trì tính minh bạch. Example.

Phiên bản dữ liệu hình ảnh;

var draw_image = function(ctx, img, sx, sy, w, h, dx, dy) { 
    var imagedata = img.ctx.getImageData(sx, sy, w, h); 
    ctx.putImageData(imagedata, dx, dy); 
}; 

Điều này có được dữ liệu hình ảnh của hình chữ nhật được yêu cầu từ cùng một canvas như được sử dụng trong phiên bản thông thường và đặt dữ liệu hình ảnh trên canvas mà tôi muốn vẽ. Tôi tin rằng sự minh bạch nên được duy trì, nhưng điều này không phải như vậy. Example. (Đây là liên kết Dropbox vì cờ origin-clean.)

Tôi có sai khi giả định rằng độ trong suốt cần được duy trì với getImageData? Hay tôi chỉ sử dụng nó một cách sai lầm?

Dù bằng cách nào, trợ giúp thực sự sẽ được đánh giá cao.

Trả lời

7

Tôi tin rằng vấn đề của bạn là putImageData không sử dụng composite operation để pha trộn dữ liệu hình ảnh nguồn và đích. Thay vào đó, nó thực hiện ghi trực tiếp các kênh màu đỏ, lục, lam, và alpha vào canvas. Đối với các pixel hoàn toàn trong suốt, điều này có nghĩa là chúng có thể hoặc không xuất hiện trong màu bạn mong đợi. Thay vào đó, bạn có thể tạo một phần tử canvas trung gian, vẽ đến đó và sau đó sử dụng drawImage() để hiển thị nó với canvas đích của bạn với áp dụng globalCompositeOperation thích hợp. Mask for putImageData with HTML5 canvas? thảo luận chi tiết hơn về vấn đề này.

Cập nhật: Bạn có thể xác minh rằng dữ liệu bạn đang viết vào ví dụ "bị hỏng" của bạn thực sự có dữ liệu trong suốt bằng cách thực hiện ctx.getImageData(230,50,1,1).data. Kết quả là [0,0,0,0] - tức là một pixel hoàn toàn trong suốt.

+1

Tôi hiểu, điều đó giải thích! Cảm ơn câu trả lời của bạn! Mặc dù, điều này thực sự ném một cờ lê trong các công trình. Tôi đã lên kế hoạch thử nghiệm nếu lợi ích của việc sử dụng 'canvas' là 'hình ảnh' trong các trò chơi (mặt nạ màu và chuyển đổi phối cảnh không có ngữ cảnh) lớn hơn chi phí hay không. Nếu tôi cần giới thiệu một khung hình trung gian để vẽ hình ảnh đã chuyển đổi, tôi cũng có thể gắn bó với việc sử dụng các đối tượng 'Hình ảnh' và một 'canvas' thô để xử lý. Cảm ơn, một lần nữa! – Rikonator

Các vấn đề liên quan