Next.jsを使って1ファイルの画像から複数サイズの画像を生成する方法
はじめに
ブログなどの記事を一覧表示する場合、下のように記事のメインイメージを縮小して表示することもよくあります。この画像はメインイメージとして準備したものなので、一覧で表示させるために何もせずCSSで縮小させた場合は表示サイズに比べてファイルサイズが大きくなってしまいます。
メインイメージ用と一覧用で2サイズの画像を準備すれば対応できますが、Next.jsを使って1ファイルの画像から複数サイズの画像を生成する方法を紹介したいと思います。
やり方
今回は例としてmicroCMSから下のフォーマットで画像のURL、height、widthを受け取ったとして説明を行います。
export type Blog = {
article_img: {
url: string;
height: number;
width: number;
};
};
使用する機能はnext/imageです。こちらは画像を最適化してくれるNext.jsの画像コンポーネントとなります。
このnext/imageに指定するheight、widthが実際の画像より小さい場合は縮小したサイズの画像ファイルを生成してくれますので、それを利用します。
具体的なコードサンプルは下の通りです。
import Image from 'next/image';
type Props = {
blog: Blog;
};
export default function Home({ blogs }: Props) {
return (
<div>
<Image
src={blog.article_img.url} alt='記事イメージ'
width={150}
height={150 * blog.article_img.height / blog.article_img.width}/>
</div>
);
}
heightへの値の設定方法を工夫しました。この意味は画像ファイルの縦横の比を保ったまま横幅150pxを基準としたheightを計算してnext/imageに渡すようにしています。こうすることでサイズの異なる画像がmicroCMSから送られてきても対応することができます。
もう少しかみ砕くと下のような数式でwidthとheightを算出しています。
width = {基準となる横幅(px)}
height = {基準となる横幅(px)} * {画像の縦幅(px)} / {画像の横幅(px)}
上のサンプルでは150としていますが、この部分を変えることでサイズ調整をすることが可能です。ただし注意点としてnext/imageはぴったり指定したサイズには縮小してくれないので、CSSでスタイルを調整する必要があります。
また、縦幅を基準としたい場合は下のように計算することで対応できます。
width = {基準となる縦幅(px)} * {画像の横幅(px)} / {画像の縦幅(px)}
height = {基準となる縦幅(px)}
終わりに
ちょっとした考慮ですが、Next.jsの機能を使って1ファイルの画像から複数サイズに対応する画像を生成することができました。複数ファイルを準備する手間が取れないときなどに参考にしてもらえれば幸いです。