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ểm | Nhượ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).