在 HTML Canvas 上使用使用者上傳的 PNG 檔案
好的,如果你想在 HTML Canvas 上使用使用者上傳的 PNG 檔案,主要涉及以下幾個步驟:
HTML 部分:提供檔案上傳控制項 你需要一個 <input type="file"> 元素讓使用者選擇檔案。 JavaScript 部分: 監聽檔案選擇事件 :當使用者選擇了檔案後,<input type="file"> 元素的 change 事件會被觸發。讀取檔案內容 :使用 FileReader API 來讀取上傳的檔案內容。對於圖片,通常會將其讀取為 Data URL。創建 Image 物件 :創建一個新的 HTMLImageElement (new Image())。設定 Image 物件的 src :將 FileReader 讀取到的 Data URL 設定為 Image 物件的 src 屬性。監聽 Image 物件的 load 事件 :圖片載入是異步的。你需要等待圖片完全載入後才能在 Canvas 上繪製它。在 load 事件回呼中繪製圖片 :一旦圖片載入完成,就可以使用 ctx.drawImage() 將其繪製到 Canvas 上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Upload PNG to Canvas</title>
<style>
body { font-family: sans-serif; display: flex; flex-direction: column; align-items: center; margin-top: 20px; }
canvas { border: 1px solid black; margin-top: 20px; }
input[type="file"] { margin-bottom: 10px; }
</style>
</head>
<body>
<label for="imageUpload">選擇一個 PNG 檔案:</label>
<input type="file" id="imageUpload" accept="image/png">
<canvas id="myCanvas" width="400" height="300"></canvas>
<script>
const imageUpload = document.getElementById('imageUpload');
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
imageUpload.addEventListener('change', function(event) {
const files = event.target.files; // 獲取選擇的檔案列表
if (files && files.length > 0) {
const file = files[0]; // 我們只處理第一個選擇的檔案
// 檢查檔案類型是否為 PNG (可選,但推薦)
if (file.type === "image/png") {
const reader = new FileReader();
// 當 FileReader 成功讀取檔案後觸發
reader.onload = function(e) {
const img = new Image(); // 創建一個新的 Image 物件
// 當 Image 物件成功載入圖片數據後觸發
img.onload = function() {
// 清除之前的畫布內容 (可選)
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 將圖片繪製到 Canvas 上
// ctx.drawImage(image, dx, dy);
// ctx.drawImage(image, dx, dy, dWidth, dHeight);
// ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// 範例1:將圖片繪製在 (0,0) 位置,使用圖片原始尺寸
// ctx.drawImage(img, 0, 0);
// 範例2:將圖片縮放/拉伸以適應 Canvas 的一部分或全部
// 例如,將圖片繪製在 (10,10),寬度200,高度150
// ctx.drawImage(img, 10, 10, 200, 150);
// 範例3:保持圖片的原始長寬比,使其適應 Canvas (較複雜,但常用)
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const imgWidth = img.naturalWidth; // 圖片的原始寬度
const imgHeight = img.naturalHeight; // 圖片的原始高度
const hRatio = canvasWidth / imgWidth;
const vRatio = canvasHeight / imgHeight;
const ratio = Math.min(hRatio, vRatio); // 取較小的縮放比例以確保圖片完整顯示
const newWidth = imgWidth * ratio;
const newHeight = imgHeight * ratio;
// 計算繪製位置,使圖片在 Canvas 中居中
const offsetX = (canvasWidth - newWidth) / 2;
const offsetY = (canvasHeight - newHeight) / 2;
ctx.drawImage(img, offsetX, offsetY, newWidth, newHeight);
console.log(`圖片 "${file.name}" 已繪製到 Canvas。`);
};
// 當 Image 物件載入圖片數據失敗時觸發
img.onerror = function() {
console.error("載入圖片時發生錯誤。");
alert("無法載入圖片。請確保檔案格式正確。");
};
// 設定 Image 物件的 src 為 FileReader 讀取到的 Data URL
// Data URL 是一個以 "data:" 開頭的 URL,它直接包含了檔案的內容
img.src = e.target.result;
};
// 當 FileReader 讀取檔案失敗時觸發
reader.onerror = function() {
console.error("讀取檔案時發生錯誤。");
alert("讀取檔案失敗。");
};
// 開始讀取檔案,將其讀取為 Data URL
reader.readAsDataURL(file);
} else {
alert("請選擇一個 PNG 格式的圖片檔案。");
// 清空檔案選擇,以便使用者可以重新選擇
event.target.value = null;
}
}
});
</script>
</body>
</html>
imageUpload.addEventListener('change', ...) :當使用者通過檔案選擇框選擇了一個或多個檔案後,這個事件會被觸發。 event.target.files 是一個 FileList 物件,包含了使用者選擇的所有檔案。我們通常取第一個 files[0]。
檔案類型檢查 (if (file.type === "image/png")) :這是一個前端的簡單檢查,可以提示使用者選擇正確的檔案類型。但這不是絕對安全的,伺服器端仍然需要進行驗證(如果檔案會上傳到伺服器的話)。
FileReader :const reader = new FileReader();:創建一個 FileReader 實例。 reader.onload = function(e) { ... }:當 FileReader 成功完成讀取操作時的回呼函數。e.target.result 將會包含讀取到的檔案內容(在這裡是 Data URL)。 reader.onerror = function() { ... }:讀取失敗時的回呼。 reader.readAsDataURL(file);:這是觸發 FileReader 開始讀取檔案的方法。它會將檔案內容編碼成一個 Base64 的 Data URL 字串。
Image 物件 :const img = new Image();:創建一個 HTMLImageElement。這和你在 HTML 中寫 <img src="..."> 是類似的,只是我們在 JavaScript 中動態創建和操作它。 img.onload = function() { ... }:這是 非常關鍵 的一步。圖片載入是異步的。你必須等到圖片的數據完全下載並解碼完成後,才能在 Canvas 上繪製它。這個回呼函數會在圖片準備好時執行。img.onerror = function() { ... }:圖片載入失敗時的回呼。 img.src = e.target.result;:將 FileReader 生成的 Data URL 賦值給 img.src。這會觸發瀏覽器開始載入圖片數據。
ctx.drawImage(image, ...) :在 img.onload 回呼中,圖片已經準備好了。 ctx.drawImage() 有多種重載形式: ctx.drawImage(image, dx, dy): 在 Canvas 的 (dx, dy) 位置繪製圖片,使用圖片的原始尺寸。 ctx.drawImage(image, dx, dy, dWidth, dHeight): 在 Canvas 的 (dx, dy) 位置繪製圖片,並將其縮放/拉伸到指定的 dWidth 和 dHeight。 ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight): (切片繪製) 從源圖片的 (sx, sy) 位置開始,截取 sWidth x sHeight 大小的區域,然後將這個區域繪製到 Canvas 的 (dx, dy) 位置,並縮放/拉伸到 dWidth x dHeight。
範例中,我提供了一個保持圖片長寬比並使其在 Canvas 中居中顯示的常用方法。img.naturalWidth 和 img.naturalHeight 用於獲取圖片的原始像素尺寸。
留言
張貼留言