【JavaScript】Canvasを使いブラウザで画像をリサイズする

フロント (ブラウザ) で画像をリサイズしたい時。ライブラリを使わずともCanvasでお手軽にリサイズできる。

async function resizeImg(file: File, width: number, height: number) {
const img = await new Promise<HTMLImageElement | null>((resolve) => {
const img = new Image();
img.addEventListener("load", () => resolve(img));
img.addEventListener("error", () => resolve(null));
img.src = URL.createObjectURL(file);
});
const context = document.createElement("canvas").getContext("2d");
if (!img || !context) return null;
context.canvas.width = width;
context.canvas.height = height;
context.drawImage(img, 0, 0, width, height);
return await new Promise<Blob | null>((resolve) =>
context.canvas.toBlob(resolve, file.type),
);
}

画像をFileとして受け取り、MIMEタイプはそのままに任意のサイズにリサイズする関数。

canvasにサイズを指定しCanvasRenderingContext2D.drawImage()で画像を描画後、それをBlob化して返している。

async function resizeImg(file: File, width: number, height: number) {
const img = await new Promise<HTMLImageElement | null>((resolve) => {
const img = new Image();
img.addEventListener("load", () => resolve(img));
img.addEventListener("error", () => resolve(null));
img.src = URL.createObjectURL(file);
});
const context = document.createElement("canvas").getContext("2d");
if (!img || !context) return null;
const { naturalWidth, naturalHeight } = img;
const newWidth =
naturalWidth > naturalHeight
? width
: Math.floor(naturalWidth * (height / naturalHeight));
const newHeight =
naturalWidth > naturalHeight
? Math.floor(naturalHeight * (width / naturalWidth))
: height;
context.canvas.width = width;
context.canvas.height = height;
context.drawImage(img, 0, 0, width, height);
context.canvas.width = newWidth;
context.canvas.height = newHeight;
context.drawImage(img, 0, 0, newWidth, newHeight);
return await new Promise<Blob | null>((resolve) =>
context.canvas.toBlob(resolve, file.type),
);
}

縦横比を保持しつつ任意の幅/高さでリサイズしたい場合は、naturalWidth/naturalHeightからもう一辺の長さを計算する。