この記事では『Canvasを使って画像をリサイズする方法』について、以下の内容をサンプルコードを用いてわかりやすく解説します。
- フロントエンドで画像リサイズを行う理由
- Canvasとは
- Canvasを使って画像をリサイズする方法
- ファイル選択ダイアログで選択した画像をCanvasでリサイズする方法
- リサイズした画像をダウンロードする方法
フロントエンドで画像リサイズを行う理由
スマートフォンやデジタルカメラの高解像度化に伴い、画像サイズが数MBに達することも多く、サーバーにアップロードする際の負荷が大きくなります。また、アップロードに時間がかかる可能性があります。
そこで、フロントエンド側で画像をリサイズすることで、以下のようなメリットが得られます。
- レスポンスの高速化
- 大きな画像はアップロードと表示に時間がかかりますが、リサイズしてから送信することで、レスポンスが速くなります。
- サーバー負荷の軽減
- クライアント側で画像をリサイズすることで、サーバー側での処理を軽減できます。
- ユーザー体験の向上
- アップロード時間が短縮され、ユーザーに快適な操作感を提供します。
この記事では、JavaScriptのCanvasを使って画像をリサイズする方法を説明します。
Canvasとは
まず、Canvasについて説明します。CanvasはWeb APIの一つで、JavaScriptを使って画像やグラフィックを動的に描画・操作するために使われています。
<canvas>
要素自体は「空の描画領域」なのでそのままでは何も表示されませんが、JavaScriptを使用してCanvas APIを操作することで、画像を描画したり、編集したりすることができるようになります。
なお、<canvas>
要素に描画する際には、2Dグラフィック用の「2Dコンテキスト」や3Dグラフィック用の「WebGLコンテキスト」を用いる必要があります。
この記事では、画像のリサイズに2Dコンテキスト(getContext('2d')
)を用いています。
キャンバス API (Canvas API) は JavaScript と HTML の <canvas> 要素によってグラフィックを描く方法を提供します。他にも、アニメーション、ゲームのグラフィック、データの可視化、写真加工、リアルタイム動画処理などに使用することができます。
https://developer.mozilla.org/ja/docs/Web/API/Canvas_API
Canvasを使って画像をリサイズする方法
Canvasを使って、画像をリサイズしているシンプルなサンプルコードを示しています。以下のサンプルコードでは、同じディレクトリ内にある画像ファイル(sample.jpg
)をリサイズして表示しています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>画像リサイズ</title>
</head>
<body>
<h3>元画像</h3>
<!-- 同じディレクトリにある画像を表示 -->
<img id="original-img" src="sample.jpg" alt="元画像" />
<h3>リサイズした画像</h3>
<img id="resized-img" src="" alt="リサイズした画像" />
<script>
// 「元画像を表示している<img>要素」と「リサイズした画像を表示する<img>要素」を取得
const originalImg = document.getElementById('original-img');
const resizedImg = document.getElementById('resized-img');
// 元画像が読み込まれると実行される
originalImg.onload = function () {
// リサイズする幅を300pxに指定し、高さはアスペクト比を維持して調整
const newWidth = 300;
const aspectRatio = originalImg.height / originalImg.width;
const newHeight = newWidth * aspectRatio;
// Canvasの作成と描画
const canvas = document.createElement('canvas'); // 新しい<canvas>要素を作成し、リサイズ用の描画エリアを設定
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d'); // Canvas に描画するために必要な CanvasRenderingContext2D を取得
ctx.drawImage(originalImg, 0, 0, newWidth, newHeight); // Canvasを使って指定した幅と高さでリサイズして画像を描画
// リサイズした画像を表示
const resizedImgDataUrl = canvas.toDataURL('image/jpeg'); // リサイズした画像をData URL形式で返す
resizedImg.src = resizedImgDataUrl;
};
</script>
</body>
</html>
上記のサンプルコードについて説明します。
HTML
<h3>元画像</h3>
<!-- 同じディレクトリにある画像を表示 -->
<img id="original-img" src="sample.jpg" alt="元画像" />
<h3>リサイズした画像</h3>
<img id="resized-img" src="" alt="リサイズした画像" />
original-img
は元画像を表示するための<img>
タグに設定している属性です。画像は同じディレクトリのsample.jpg
を使用します。
resized-img
はリサイズした画像を表示するための<img>
タグに設定している属性です。リサイズした画像をここに表示します。
JavaScript
HTML要素の取得
// 「元画像を表示している<img>要素」と「リサイズした画像を表示する<img>要素」を取得
const originalImg = document.getElementById('original-img');
const resizedImg = document.getElementById('resized-img');
「元画像を表示している<img>
要素」と「リサイズした画像を表示する<img>
要素」を取得しています。
元画像の読み込み
originalImg.onload = function () {
...
}
元画像を表示している要素(originalImg
)の読み込みが完了すると、onload
イベントが発火します。
リサイズする幅と高さの指定
// リサイズする幅を300pxに指定し、高さはアスペクト比を維持して調整
const newWidth = 300;
const aspectRatio = originalImg.height / originalImg.width;
const newHeight = newWidth * aspectRatio;
リサイズする幅と高さを指定しています。高さはアスペクト比を維持して調整しています。
Canvasの作成と描画
// Canvasの作成と描画
const canvas = document.createElement('canvas'); // 新しい<canvas>要素を作成し、リサイズ用の描画エリアを設定
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d'); // Canvas に描画するために必要な CanvasRenderingContext2D を取得
ctx.drawImage(originalImg, 0, 0, newWidth, newHeight); // Canvasを使って指定した幅と高さでリサイズして画像を描画
新しい<canvas>
要素を作成し、リサイズ用の描画エリアを設定しています。また、リサイズした画像サイズに合わせて、Canvasのwidth
とheight
を設定しています。
getContext('2d')
を使用してCanvasRenderingContext2D
を取得しています。これにより、2Dの描画操作が可能になります。
drawImage
メソッドを使用して、元画像をCanvasに描画しています。引数に新しい幅と高さを指定することで、指定したサイズにリサイズしています。
リサイズした画像を表示
// リサイズした画像を表示
const resizedImgDataUrl = canvas.toDataURL('image/jpeg'); // リサイズした画像をData URL形式で返す
resizedImg.src = resizedImgDataUrl;
canvas.toDataURL('image/jpeg')
では、Canvasの内容をJPEG形式の「Data URL」に変換しています。このData URLは、画像を文字列の形式に変えたもので、Data URLをHTMLのsrc
属性に使うことで画像を直接表示することができます。また、ダウンロードリンクにも使用することができます。このData URLをresizedImg.src
に設定することで、リサイズした画像がHTML上に表示されます。
ファイル選択ダイアログで選択した画像をCanvasでリサイズする方法
次に、ファイル選択ダイアログで選択した画像をCanvasを使ってリサイズしているサンプルコードを以下に示します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>画像リサイズ</title>
</head>
<body>
<!-- 画像選択:<input type="file">でファイルを選択すると、fileup関数が発火します。 -->
<input type="file" accept="image/jpeg,image/png,image/gif" onchange="fileup(this)" />
<h3>選択された画像</h3>
<img id="original-img" src="" alt="元画像" />
<h3>リサイズした画像</h3>
<img id="resized-img" src="" alt="リサイズした画像" />
<script>
// 「元画像を表示する<img>要素」と「リサイズした画像を表示する<img>要素」を取得
const originalImg = document.getElementById('original-img');
const resizedImg = document.getElementById('resized-img');
// fileup関数内の処理
function fileup(input) {
// 選択された画像ファイルを読み込むためのFileReaderオブジェクトを作成
const reader = new FileReader();
reader.onload = function () {
// 画像処理用のHTMLImageElementオブジェクトの作成
const imgReader = new Image();
imgReader.onload = function () {
// 選択された画像を表示
originalImg.src = reader.result;
// 画像タイプ取得
const imgType = imgReader.src.substring(5, imgReader.src.indexOf(';'));
// リサイズする幅を300pxに指定し、高さはアスペクト比を維持して調整
const newWidth = 300;
const aspectRatio = imgReader.height / imgReader.width;
const newHeight = newWidth * aspectRatio;
// Canvasの作成と描画
const canvas = document.createElement('canvas'); // 新しい<canvas>要素を作成し、リサイズ用の描画エリアを設定
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d'); // Canvas に描画するために必要な CanvasRenderingContext2D を取得
ctx.drawImage(imgReader, 0, 0, newWidth, newHeight); // Canvasを使って指定した幅と高さでリサイズして画像を描画
// リサイズした画像を表示
const resizedImgDataUrl = canvas.toDataURL(imgType); // リサイズした画像をData URL形式で返す
resizedImg.src = resizedImgDataUrl;
};
// 画像ソースを指定し、画像を読み込む
imgReader.src = reader.result;
};
// 選択されたファイルをData URL形式で読み込む
reader.readAsDataURL(input.files[0]);
}
</script>
</body>
</html>
上記のサンプルコードについて説明します。
HTML
<input type="file" accept="image/jpeg,image/png,image/gif" onchange="fileup(this)" />
<input type="file">
要素を使用します。この要素をクリックすると、ファイル選択ダイアログが開きます。onchange
でファイル選択後にfileup
イベントが発火します。
JavaScript
選択されたファイルをData URL形式で読み込む
function fileup(input) {
// 選択された画像ファイルを読み込むためのFileReaderオブジェクトを作成
const reader = new FileReader();
reader.onload = function () {
...
};
reader.readAsDataURL(input.files[0]);
}
reader.readAsDataURL(input.files[0])
によって、選択されたファイルをData URL形式で読み込んでいます。読み込みが完了すると、reader.onload
イベントが発火します。
読み込んだ画像をHTMLImageElementオブジェクトに変換
// 画像処理用のHTMLImageElementオブジェクトの作成
const imgReader = new Image();
imgReader.onload = () => {
...
};
// HTMLImageElementオブジェクトのsrcにFileReaderのresultプロパティを設定
imgReader.src = reader.result;
imgReader.src = reader.result
で、HTMLImageElement
オブジェクトのsrc
プロパティにFileReader
オブジェクトのresult
プロパティを設定しています。この処理では、HTMLImageElement
オブジェクトにFileReader
で読み込んだ画像データを設定しています。設定後、imgReader.onload
イベントが発火します。
【補足】リファクタリング
各処理を分割すると以下のようになります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>画像リサイズ</title>
</head>
<body>
<!-- 画像選択:<input type="file">でファイルを選択すると、fileup関数が発火します。 -->
<input type="file" accept="image/jpeg,image/png,image/gif" onchange="fileup(this)" />
<h3>選択された画像</h3>
<img id="original-img" src="" alt="元画像" />
<h3>リサイズした画像</h3>
<img id="resized-img" src="" alt="リサイズした画像" />
<script>
// 「元画像を表示する<img>要素」と「リサイズした画像を表示する<img>要素」を取得
const originalImg = document.getElementById('original-img');
const resizedImg = document.getElementById('resized-img');
// 画像ファイルをData URL形式で読み込み、Data URLを返す
const readAsDataURL = function (imgFile) {
return new Promise((resolve) => {
// 選択された画像ファイルを読み込むためのFileReaderオブジェクトを作成
const reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
// 選択されたファイルをData URL形式で読み込む
reader.readAsDataURL(imgFile);
});
};
// 画像のURLを元にHTMLImageElementオブジェクトを作成し、読み込んだ画像を返す
const loadImage = function (src) {
return new Promise((resolve) => {
// 画像処理用のHTMLImageElementオブジェクトの作成
const imgReader = new Image();
imgReader.onload = function () {
resolve(imgReader);
};
// 画像ソースを指定し、画像を読み込む
imgReader.src = src;
});
};
// HTMLImageElementオブジェクトからリサイズした画像のData URLを生成して返す
const resizeImgAndOutputDataUrl = function (img) {
// MIMEタイプを取得
const imgType = img.src.substring(5, img.src.indexOf(';'));
// リサイズする幅を300pxに指定し、高さはアスペクト比を維持して調整
const newWidth = 300;
const aspectRatio = img.height / img.width;
const newHeight = newWidth * aspectRatio;
// Canvasの作成・Canvasへの描画:
const canvas = document.createElement('canvas'); //Canvasの作成
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d'); // Canvas に描画するために必要な CanvasRenderingContext2D を取得
ctx.drawImage(img, 0, 0, newWidth, newHeight); // Canvasを使って指定した幅と高さでリサイズして画像を描画
return canvas.toDataURL(imgType); // リサイズした画像をData URL形式で返す
};
// fileup関数内の処理
async function fileup(input) {
// 選択された画像ファイルをData URL形式で取得
const inputImgDataUrl = await readAsDataURL(input.files[0]);
// 元画像を表示
originalImg.src = inputImgDataUrl;
// Data URLからHTMLImageElementオブジェクトを作成
const inputImg = await loadImage(inputImgDataUrl);
// HTMLImageElementオブジェクトをリサイズしてData URL形式で取得
const resizedImgDataUrl = resizeImgAndOutputDataUrl(inputImg);
// リサイズした画像を表示
resizedImg.src = resizedImgDataUrl;
}
</script>
</body>
</html>
リサイズした画像をダウンロードする方法
以下のサンプルコードでは、ファイル選択ダイアログで開いた画像をCanvasを使ってリサイズし、そのリサイズ画像をダウンロードできるようにしています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>画像リサイズ</title>
</head>
<body>
<!-- 画像選択:<input type="file">でファイルを選択すると、fileup関数が発火します。 -->
<input type="file" accept="image/jpeg,image/png,image/gif" onchange="fileup(this)" />
<h3>選択された画像</h3>
<img id="original-img" src="" alt="元画像" />
<h3>リサイズした画像</h3>
<img id="resized-img" src="" alt="リサイズした画像" />
<p><a id="download" href="#" download="no-name.png">ダウンロード</a></p>
<script>
// 「元画像を表示する<img>要素」と「リサイズした画像を表示する<img>要素」を取得
const originalImg = document.getElementById('original-img');
const resizedImg = document.getElementById('resized-img');
// fileup関数内の処理
function fileup(input) {
// 選択された画像ファイルを読み込むためのFileReaderオブジェクトを作成
const reader = new FileReader();
reader.onload = function () {
// 画像処理用のHTMLImageElementオブジェクトの作成
const imgReader = new Image();
imgReader.onload = function () {
// 選択された画像を表示
originalImg.src = reader.result;
// 画像タイプ取得
const imgType = imgReader.src.substring(5, imgReader.src.indexOf(';'));
// リサイズする幅を300pxに指定し、高さはアスペクト比を維持して調整
const newWidth = 300;
const aspectRatio = imgReader.height / imgReader.width;
const newHeight = newWidth * aspectRatio;
// Canvasの作成と描画
const canvas = document.createElement('canvas'); // 新しい<canvas>要素を作成し、リサイズ用の描画エリアを設定
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d'); // Canvas に描画するために必要な CanvasRenderingContext2D を取得
ctx.drawImage(imgReader, 0, 0, newWidth, newHeight); // Canvasを使って指定した幅と高さでリサイズして画像を描画
// リサイズした画像を表示
const resizedImgDataUrl = canvas.toDataURL(imgType); // リサイズした画像をData URL形式で返す
resizedImg.src = resizedImgDataUrl;
// ダウンロード設定:リサイズした画像をダウンロードできるようにします。
const dl = document.getElementById('download');
dl.href = resizedImgDataUrl;
// 元のファイル名を取得
const originalFile = input.files[0];
const originalFileName = originalFile.name;
// ダウンロードのファイル名を変更
dl.download = `resized_${originalFileName}`;
};
// 画像ソースを指定し、画像を読み込む
imgReader.src = reader.result;
};
// 選択されたファイルをData URL形式で読み込む
reader.readAsDataURL(input.files[0]);
}
</script>
</body>
</html>
HTML
<a id="download" href="#" download="no-name.png">ダウンロード</a>
<a>
タグはリンクとして機能しますが、download
属性を設定することで、リンク先のファイルをダウンロードできるようにしています。この属性にはダウンロードファイルのファイル名も指定でき、ここでは初期設定として"no-name.png"
としています。クリックするとリサイズした画像がダウンロードされます。
JavaScript
ダウンロード設定
// ダウンロード設定:リサイズした画像をダウンロードできるようにします。
const dl = document.getElementById('download');
dl.href = resizedImgDataUrl;
// 元のファイル名を取得
const originalFile = input.files[0];
const originalFileName = originalFile.name;
// ダウンロードのファイル名を変更
dl.download = `resized_${originalFileName}`;
dl.href = resizedImgDataUrl
では、リサイズした画像のData URLをリンクのhref
属性に設定しています。これにより、リンクをクリックしたときにリサイズ画像がダウンロードされるようになります。
また、selectedFileName
には、選択された元ファイルの名前が格納されているため、この名前に基づいてdownload
属性をresized_${selectedFileName}
に更新しています。これにより、ダウンロードしたファイルの名前は元のファイル名にresized_
を加えた名前になります。
本記事のまとめ
この記事では『Canvasを使って画像をリサイズする方法』について、以下の内容を説明しました。
- フロントエンドで画像リサイズを行う理由
- サーバー負荷の軽減、レスポンスの高速化、ユーザー体験の向上。
- Canvasとは
- HTMLの
<canvas>
要素とJavaScriptのCanvas APIを使い、動的な画像描画や操作が可能。
- HTMLの
- Canvasを使って画像をリサイズする方法
- JavaScriptで
<canvas>
要素を作成し、指定した幅と高さで画像を描画。 drawImage()
を用いてアスペクト比を保持したリサイズ。
- JavaScriptで
- ファイル選択ダイアログを利用した画像リサイズ
<input type="file">
を利用し、選択画像をCanvasでリサイズ。
- リサイズした画像をダウンロードする方法
toDataURL()
でData URLを取得し、リンクのhref
属性に設定してダウンロード可能に。
- サンプルコードのリファクタリング
- 各処理を関数化し、可読性を向上。
お読み頂きありがとうございました。