RavelloH's Blog

LOADing...



Nextjs使用ImageResponse动态裁剪图像

nextjs-dynamic-image-cropping-with-imageresponse

技术/设计 3434

nextjs图像处理


很多时候manifest.json等文件会要求我们给它一系列尺寸的 icon 图片, 虽然生成起来也不算太麻烦,例如有像PWABuilder这样的工具, 但若是经常变动 icon 的话还是觉得有点麻烦,于是想能不能用 nextjs 来动态生成这些图片。

ImageResponse

ImageResponse是 nextjs 13.4 引入的一个新特性,可以用来动态生成react组件的图片, 加上个img标签,再调一下画布大小,就非常适合用来生成 icon 图片。

使用

下面是一个我现在正在用的例子,只需要更改 iconPath 的定义,并创建个app/icon.js即可使用

import \{ ImageResponse } from "next/og";

const iconPath =
  "https://ravelloh.top/assets/images/android-chrome-512x512.png";

export function generateImageMetadata() \{
  return [
    \{
      contentType: "image/png",
      size: \{ width: 16, height: 16 },
      id: "16x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 32, height: 32 },
      id: "32x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 36, height: 36 },
      id: "36x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 48, height: 48 },
      id: "48x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 72, height: 72 },
      id: "72x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 96, height: 96 },
      id: "96x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 128, height: 128 },
      id: "128x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 144, height: 144 },
      id: "144x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 192, height: 192 },
      id: "192x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 256, height: 256 },
      id: "256x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 384, height: 384 },
      id: "384x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 512, height: 512 },
      id: "512x",
    },
    \{
      contentType: "image/png",
      size: \{ width: 1024, height: 1024 },
      id: "1024x",
    },
  ];
}

export default async function Icon(\{ id }) \{
  return new ImageResponse(
    (
      // eslint-disable-next-line @next/next/no-img-element
      <img src=\{iconPath} width="100%" height="100%" alt="Icon" />
    ),
    \{
      width: id.replace("x", ""),
      height: id.replace("x", ""),
    }
  );
}

Nextjs 默认会自动在 build 时 SSR 这些 icon,即每次部署后会自动更新。 请求起来也很简单,例如要是要 144x144 的 icon,只需要访问/icon/144x即可。 对应的 manifest.js 中的 icon 配置如下:

icons: [
     \{
         src: '/icon/16x/',
         sizes: '16x16',
         type: 'image/png',
     },
     \{
         src: '/icon/32x/',
         sizes: '32x32',
         type: 'image/png',
     },
     \{
         src: '/icon/36x/',
         sizes: '36x36',
         type: 'image/png',
     },
     \{
         src: '/icon/48x/',
         sizes: '48x48',
         type: 'image/png',
     },

     \{
         src: '/icon/72x/',
         sizes: '72x72',
         type: 'image/png',
     },

     \{
         src: '/icon/96x/',
         sizes: '96x96',
         type: 'image/png',
     },
     \{
         src: '/icon/128x/',
         sizes: '128x128',
         type: 'image/png',
     },
     \{
         src: '/icon/144x/',
         sizes: '144x144',
         type: 'image/png',
     },

     \{
         src: '/icon/192x/',
         sizes: '192x192',
         type: 'image/png',
     },
     \{
         src: '/icon/512x/',
         sizes: '512x512',
         type: 'image/png',
     },

     \{
         src: '/icon/1024x/',
         sizes: '1024x1024',
         type: 'image/png',
     }
 ]
INFO

00:00


无正在播放的音乐
00:00/00:00

账号
User avatar
未登录未设置描述...