Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> HTML

Vẽ hình ảnh từ Data URL lên HTML5 Canvas

Data URL (Base64 encoded) có thể vẽ trực tiếp lên canvas bằng cách tạo đối tượng Image và gán src = data URL.

Cách cơ bản

var ctx = canvas.getContext('2d');
var img = new Image();

img.onload = function() {
  ctx.drawImage(img, 0, 0); // Vẽ tại (0,0) kích thước gốc
  // Hoặc co giãn: ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};

img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...'; // Data URL

Ví dụ hoàn chỉnh: Chuyển canvas sang Data URL và vẽ ngược lại

<!DOCTYPE html>
<html>
<body>
  <canvas id="sourceCanvas" width="200" height="200" style="border:1px solid red"></canvas>
  <canvas id="destCanvas" width="200" height="200" style="border:1px solid blue"></canvas>
  <br>
  <button onclick="copyCanvas()">Copy Source → Dest qua Data URL</button>
  
  <script>
    var srcCanvas = document.getElementById('sourceCanvas');
    var destCanvas = document.getElementById('destCanvas');
    var srcCtx = srcCanvas.getContext('2d');
    var destCtx = destCanvas.getContext('2d');
    
    // Vẽ hình lên source
    srcCtx.fillStyle = 'red';
    srcCtx.fillRect(20, 20, 80, 80);
    srcCtx.fillStyle = 'blue';
    srcCtx.beginPath();
    srcCtx.arc(150, 150, 30, 0, Math.PI*2);
    srcCtx.fill();
    
    function copyCanvas() {
      // 1. Lấy Data URL từ source canvas
      var dataURL = srcCanvas.toDataURL('image/png');
      
      // 2. Tạo Image từ Data URL
      var img = new Image();
      img.onload = function() {
        // 3. Vẽ lên destination canvas
        destCtx.clearRect(0, 0, destCanvas.width, destCanvas.height);
        destCtx.drawImage(img, 0, 0);
      };
      img.src = dataURL;
    }
  </script>
</body>
</html>

Ưu/Nhược điểm Data URL

Ưu điểmNhược điểm
Tự chứa (self-contained), không cần request mạng Kích thước lớn hơn binary ~33% (Base64 overhead)
Dễ embed trong CSS, JSON, localStorage Không cache được riêng biệt bởi browser
Cross-origin an toàn (same-origin) Block main thread khi decode ảnh lớn

Cách tốt hơn: OffscreenCanvas / createImageBitmap (Modern)

// Tạo ImageBitmap từ blob/data (async, off main thread)
const blob = await fetch(dataURL).then(r => r.blob());
const bitmap = await createImageBitmap(blob);
ctx.drawImage(bitmap, 0, 0); // Vẽ cực nhanh, không block UI

Lưu ý bảo mật

  • Data URL từ nguồn không tin cậy có thể chứa script (SVG) → nguy hiểm nếu inject vào DOM.
  • Canvas vẽ từ Data URL cross-origin không bị tainted (vì same-origin).