Next.js和sharp实现占位图片生成工具

news2024/11/17 5:20:20

占位图片(Placeholder Image) 是前端开发中常用的工具,用于在网页加载慢或未加载完整的情况下,为图像元素提供占位。但是,有时候我们需要更灵活的方式来生成自定义占位图片以满足特定需求。在这篇博客中,我们将介绍如何使用 Next.js sharp 框架来实现一个占位图片生成工具,使你能够根据需要生成自定义占位图片。

占位图片生成工具

  • 上链接🔗:https://next-blog.tiven.cn/api/g/400/200,展示效果如上
  • 使用文档🔗:自定义占位图片生成工具使用文档

一、占位图片生成工具的作用

占位图片生成工具是一个用于动态生成占位图片的应用程序,其作用如下:

作用:

  1. 自定义占位图片生成: 通过该工具,你可以根据自己的需求生成各种自定义占位图片。这些图片可以包括不同的尺寸、颜色、文字内容和样式。
  2. 提高开发效率: 在前端开发中,经常需要使用占位图片来展示图像占位,而手动创建这些占位图片是繁琐的。占位图片生成工具可以大大提高开发效率。
  3. 支持不同格式: 该工具支持生成 SVGPNG 格式的占位图片,以适应不同的项目需求。

二、使用场景

  1. 网站开发: 在网站开发中,占位图片用于占据图像元素的位置,以便在图像加载时提供视觉反馈。生成工具可根据网页布局生成符合尺寸和颜色要求的占位图片。
  2. 移动应用开发: 移动应用通常包含大量图像元素,使用占位图片可以提高应用的加载速度和性能。生成工具可为移动应用生成符合规格的占位图片。
  3. 设计师协作: 占位图片生成工具也可以在设计师和开发者之间发挥作用。设计师可以使用工具生成占位图,以占据设计中的图像空白区域,从而更好地展示设计意图。
  4. 自定义测试数据: 在开发和测试过程中,你可以使用占位图片作为测试数据,以确保应用程序正确处理图像元素的情况。

三、实现占位图片生成工具

以下是基于 Next.js 框架和 sharp 图片处理库实现的占位图片生成工具的示例代码。你可以在本地运行这个示例,以便更好地理解如何实现占位图片生成工具。

步骤1:创建Next.js项目

首先,让我们创建一个Next.js项目,以便开始构建我们的占位图片生成工具。使用以下命令初始化一个新项目:

npx create-next-app placeholder-image-generator
cd placeholder-image-generator

步骤2:设置API路由

在Next.js中,我们可以使用API路由来创建服务器端端点。我们将创建一个API路由,它将处理占位图片的生成请求。在项目根目录下创建一个名为 pages/api/g/[...px].js 的文件,这将是我们的生成工具的入口点。

// pages/api/g/[...px].js

import sharp from 'sharp'
const colorString = require('color-string')

export default async function handler(req, res) {
  try {
    // 解析请求参数
    let { px, text, bg, color, size, type } = req.query;

    // 处理参数并设置默认值
    let [w, h] = px?.length >= 2 ? px : [200, 200];
    text = text || `${w} x ${h}`;
    bg = bg || 'ccc';
    color = color || '666';
    size = size || 32;

    // 处理颜色参数
    const bgRes = colorString.get(bg) || colorString.get(`#${bg}`);
    let bgStr = bgRes ? colorString.to.hex(bgRes.value) : '#ccc';
    const colorRes = colorString.get(color) || colorString.get(`#${color}`);
    let colorStr = colorRes ? colorString.to.hex(colorRes.value) : '#666';

    // 生成SVG图像
    let ratio = 1;
    let buffer = getSvgBuffer({
      w: ratio * w,
      h: ratio * h,
      bg: bgStr,
      color: colorStr,
      size,
      text,
    });

    // 根据类型响应不同格式的图像
    if (type === 'svg') {
      res.status(200).setHeader('Content-Type', 'image/svg+xml');
      res.end(buffer);
    } else {
      const img = await sharp(buffer, {
        density: 1000,
      })
          .withMetadata({
            density: 1000,
            quality: 100,
          })
          .png({
            palette: true,
            quality: 100,
            compressionLevel: 3,
          })
          .resize({
            width: +w,
            height: +h,
            fit: 'contain',
          })
          .toBuffer();

      res.status(200).setHeader('Content-Type', 'image/png');
      res.end(img);
    }
  } catch (e) {
    res.status(200).setHeader('Content-Type', 'text/html; charset=utf-8');
    res.end(getErrorHtml());
  }
}

步骤3:生成SVG图像的函数

我们在上述代码中使用了名为 getSvgBuffer 的函数来生成SVG图像。这个函数接受参数,包括宽度、高度、背景颜色、文字颜色、文字内容和文字大小。

function getSvgBuffer({ w, h, bg, color, size, text }) {
  let textY = (+h + size / 2) / 2;
  let svg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" version="1.1"
     width="${w}" height="${h}">
    <rect width="${w}" height="${h}"
    fill="${bg}" style="fill:${bg};"/>
    <text x="50%" y="${textY}" 
    dominant-baseline="alphabetic" text-anchor="middle" 
    fill="none" stroke="${color}" font-size="${size}" 
    style="font-family:Verdana, Arial, lobster, Helvetica,fantasy,fangsong,monospace,emoji,'Gill Sans',system-ui,serif,Georgia,Times,'Times New Roman','黑体','STXingkai';" 
    fill-opacity="1">${text}</text>
  </svg>`;
  return Buffer.from(svg);
}

步骤4:处理错误情况

在上述代码中,我们使用 getErrorHtml 函数来生成包含错误信息的HTML页面。这是一个简单的HTML模板,用于在发生错误时向用户提供错误信息。

function getErrorHtml() {
  let basePath = process.env.BASE_PATH
  
  let publicPath = `${basePath}/api/g`
  let backHome =
    process.env.NODE_ENV === 'development'
      ? `<a style="font-size: 16px;" href="/">← 返回首页</a>`
      : ''
  return `
    <head>
      <link rel="icon" href="${basePath}/favicon.ico">
      <title>自定义占位图</title>
      <style>
      code {
        color: #98c379;
      }
      table {
        border-collapse: collapse;
        width: 600px;
      }
      th, td {
        padding: 5px 10px;
        text-align: left;
      }
      .box {
        padding: 20px 50px;
      }
      .back {
        display: flex;
        justify-content: space-between;
        align-items: center;
      }
      .img {
        display: block;
        margin: 10px 0;
      }
      </style>
    </head>
    <div class="box">
      <h1 class="back">
        URL 地址异常
        ${backHome}
      </h1>
      <p>URL格式参考如下:</p>
      <ol>
      <li>
        默认:<a href="${publicPath}/200/200">${publicPath}/200/200</a>
        <br>
        <img style="width: 200px; height: 200px" class="img" src="${publicPath}/200/200" alt="tiven-img"> 
      </li>
      <li>
        Svg占位图:<a href="${publicPath}/200/100?type=svg&bg=FEDC9B">${publicPath}/200/100?type=svg&bg=FEDC9B</a>
        <br>
        <img style="width: 200px; height: 100px" class="img" src="${publicPath}/200/100?type=svg&bg=FEDC9B" alt="tiven-img"> 
      </li>
      <li>
        自定义大小:<a href="${publicPath}/640/320">${publicPath}/640/320</a>
        <br>
        <img style="width: 640px; height: 320px" class="img" src="${publicPath}/640/320" alt="tiven-img"> 
      </li>
      <li>
        自定义内容:<a href="${publicPath}/400/200?bg=palevioletred&color=purple&text=React&size=30">${publicPath}/400/200?bg=palevioletred&color=purple&text=React&size=30</a>
        <br>
        <img style="width: 400px; height: 200px" class="img" src="${publicPath}/400/200?bg=palevioletred&color=purple&text=React&size=30" alt="tiven-img">  
      </li>
      </ol>
      <table border="1" borderColor="#ddd">
      <tr>
      <th>参数(可选)</th>
      <th>作用</th>
      </tr>
      <tr>
      <td>bg</td>
      <td>背景色,默认:<code>#ccc</code></td>
      </tr>
      <tr>
      <td>color</td>
      <td>文字颜色,默认:<code>#666</code></td>
      </tr>
      <tr>
      <td>text</td>
      <td>文字,默认:<code>200x200</code> ( width x height )</td>
      </tr>
      <tr>
      <td>size</td>
      <td>文字大小,默认:<code>32</code></td>
      </tr>
      <tr>
      <td>type</td>
      <td>占位图类型,默认:<code>png</code>,可选 svg</td>
      </tr>
      </table>
      <p><b>bg</b>,<b>color</b> 颜色参数可以传 <u>hex类型</u> 的值:<code>50A6EE</code>,<code>f00</code>;</p>
      <p>也可以传表示颜色的 <u>英文单词</u> :<code>red</code>、<code>pink</code>、<code>red</code>等。</p>
      <p style="font-size: 20px;">完整技术实现博客:<a href="https://tiven.cn/p/aa610ce5/" target="_blank" title="Next.js和sharp实现占位图片生成工具">Next.js和sharp实现占位图片生成工具</a></p>
    </div>
    `
}

步骤5:运行和测试

现在,你可以启动你的 Next.js 应用程序并测试占位图片生成工具。运行以下命令:

npm run dev

然后,在浏览器中访问 http://localhost:3000/api/g/400/200 ,并尝试不同的参数组合,以生成自定义的占位图片。

四、总结

在这篇博客中,我们深入探讨了如何使用 Next.js 框架和 sharp 图片处理库创建一个占位图片生成工具。这个工具允许你根据用户的参数生成自定义占位图片,非常适合前端开发中的图像占位需求。通过这个示例,你可以学习如何设置API路由、处理请求参数、生成SVG图像和处理错误情况。这将使你在前端开发中更加灵活,满足不同项目的需求。无论是网站开发、移动应用开发还是设计师和开发者之间的协作,占位图片生成工具都可以提高工作效率,改善用户体验。


欢迎访问:天问博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1115922.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ArGIS Engine专题(14)之GP模型根据导入范围与地图服务相交实现叠置分析

一、结果预览 二、需求简介 前端系统开发时,可能遇到如下场景,如客户给出一个图斑范围,导入到系统中后,需要判断图斑是否与耕地红线等地图服务存在叠加,叠加的面积有多少。虽然arcgis api中提供了相交inserect接口,但只是针对图形几何之间的相交,如何要使用该接口,则需…

文件对比工具Beyond Compare 4(4.4.7) for Mac

Beyond Compare 4 是一款强大的文件和文件夹比较工具。它提供了一个直观的界面&#xff0c;使您可以快速比较和同步文件和文件夹。 Beyond Compare 4 具有许多有用的功能&#xff0c;包括比较和合并文件、文件夹和压缩文件&#xff0c;以及同步文件和文件夹。它支持各种类型的文…

C++新经典 | C++ 查漏补缺(STL标准模板库)

目录 一、STL总述 1.容器 &#xff08;1&#xff09;顺序容器 &#xff08;2&#xff09;关联容器 &#xff08;3&#xff09;无序容器 &#xff08;4&#xff09;常用容器 &#xff08;4.1&#xff09;array 数组 &#xff08;4.2&#xff09;vector &#xff08;4.3…

软件功能测试的6种方法

对于测试人员而言&#xff0c;软件产品每个按钮的功能是否准确&#xff0c;链接是否能正常跳转&#xff0c;搜索时会不会出现页面错误&#xff0c;验证并减少这些软件使用过程中可能出现的各种小问题都是功能测试的内容。而对于用户而言&#xff0c;功能能否正常执行都是非常直…

Visual Components软件有哪些用途 衡祖仿真

Visual Components是一款用于制造业虚拟仿真的软件&#xff0c;主要用于工业自动化和制造领域。我们一起来看一下该软件有哪些功能吧&#xff01; 1、工厂仿真 Visual Components可以建立虚拟的工厂环境&#xff0c;模拟和优化生产流程。用户可以创建工厂布局、定义设备和机器人…

【试题031】C语言关系运算符和逻辑非例题

1.题目&#xff1a; 设int p;&#xff0c;与if(p0)等价的是 () A if(p) B if(!p) if(p1) Dif(p!0) 2.分析&#xff1a; [ ] if中的条件是p0为真&#xff0c;也就是说p0[ ] 那么&#xff01;p1,逻辑非就是将结果取反的操作[ ] p0也就是p≠1 3.截图&#xff1a;

KT142C语音芯片直接焊到我的板子上面,插上usb,但是出不来虚拟U盘怎么办

KT142C的芯片&#xff0c;我直接焊到我的板子上面&#xff0c;插上usb&#xff0c;但是出不来虚拟U盘怎么办&#xff1f; 1、这个问题&#xff0c;其实最好的解决方案&#xff0c;就是对比我们的测试板&#xff0c;因为出现这种情况&#xff0c;不好找原因 2、但是有测试板的话…

【Arduino32】PWM控制直流电机速度

硬件准备 震动传感器&#xff1a;1个 红黄绿LED灯&#xff1a;各一个 旋钮电位器&#xff1a;1个 直流电机&#xff1a;1个 1K电阻&#xff1a;1个 220欧电阻&#xff1a;3个 杜邦线&#xff1a;若干 硬件连线 软件程序 const int analogInPin A0;//PWM输入引脚 const…

AWS SAP-C02教程8-大数据和机器学习

接下来是一个组跟数据和机器学习有关的内容,这部分在SAP-C02考试中目前占比可能不多且不是很深入,但是随着AI的趋势,这部分内容将会越来越重要,但是经常会出现在考题的选项中,因此了解其基本功能和在解决方案中的应用也是非常重要的。 目录 1 大数据1.1 Kinesis家族1.1.1…

JMeter添加插件

一、前言 ​ 在我们的工作中&#xff0c;我们可以利用一些插件来帮助我们更好的进行性能测试。今天我们来介绍下Jmeter怎么添加插件&#xff1f; 二、插件管理器 ​ 首先我们需要下载插件管理器jar包 下载地址&#xff1a;Install :: JMeter-Plugins.org 然后我们将下载下来…

Docker-镜像的备份迁移及私有仓库的搭建

一、Docker-备份与迁移 A服务器系统配置 B服务器系统配置 1.用命令将容器保存为镜像。 案例&#xff0c;将A服务器的Docker容器迁移到另外一台服务器B&#xff0c;A服务器的容器配置过对应的文件&#xff0c;不想在B服务器重新搭建&#xff0c;可以使用该案例。 docker c…

vue 组件封装 综合案例1

vue 组件封装 综合案例 **创建 工程&#xff1a; H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\11-综合案例-商品列表 vue --version vue c…

2023年中国游戏机设备分类、销量及市场规模分析[图]

游戏机设备行业是指生产和销售游戏机设备的行业&#xff0c;包括游戏机硬件、游戏软件、游戏周边设备等。随着科技的进步和游戏市场的不断扩大&#xff0c;游戏机设备行业也在不断发展和和创新。 游戏机设备分类 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff…

关于setInteval定时器在不同浏览器下表现差异

背景: 项目下用到websocket, 中间使用了setInterval 定时向服务端发送心跳包, 5s/次, 观察正常, 就将浏览器最小化后, 经过了两天, 周一过来查看, 咋才 5000次; 问题分析: 遇到这种简单的问题当然是请教一下GPT 来的最快最实际, 不出所料, 马上得到证实; chrome 88 版本之…

CentOS7.9离线安装 Nginx

1. 下载Nginx安装包 下载地址&#xff1a;http://nginx.org/download/nginx-1.20.1.tar.gzhttp://nginx.org/download/nginx-1.20.1.tar.gz 2. 找到Nginx安装时需要的依赖包 我这里是下载了CentOS7.9的安装镜像 阿里下载地址&#xff1a;centos-7.9.2009-isos-x86_64安装包…

大白话聊AVL树

文章目录 前言AVL树的平衡性不平衡的几种情况AVL树恢复平衡LL恢复平衡RR恢复平衡LR恢复平衡RL恢复平衡 总结 前言 上文对常见的数据结构进行了简单介绍&#xff0c;包括它们的定义、性质和特点。本文将对AVL树展开介绍&#xff0c;通过对AVL树的插入、删除、查找以及旋转操作全…

CleanMyMac X4.14.4最新免费版本功能介绍

最新版CleanMyMac X 让您的Mac焕然一新&#xff0c;时刻保持安全&#xff01;CleanMyMac X是一款专业的Mac清理软件&#xff0c;可智能清理mac磁盘垃圾和多余语言安装包&#xff0c;快速释放电脑内存&#xff0c;轻松管理和升级Mac上的应用。同时CleanMyMac X可以强力卸载恶意软…

力扣第332题 重新安排行程 c++ 难

题目 332. 重新安排行程 困难 相关标签 深度优先搜索 图 欧回路 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机…

通达信神奇九转指标原理及选股公式,无未来函数,数字不消失

神奇九转指标的原理源自技术分析师汤姆迪马克(Tom Demark)发明的TD序列&#xff0c;用于识别趋势衰竭和价格反转的时间。神奇九转指标是一种震荡指标&#xff0c;目的在于解决一些技术分析指标在趋势行情中有利可图&#xff0c;但在震荡行情中表现很差的问题。 一、神奇九转指标…

算法通关村第19关【白银】| 动态规划高频问题

1.零钱兑换 思路&#xff1a; 确定dp&#xff1a;这里是最少硬币的个数&#xff0c;不是种类 确定递推公式&#xff1a;dp[j] Math.min(dp[j],dp[j-coins[i]]1),不要当前硬币dp[j]还是保持以前的组合方法,要当前硬币dp[j-coins[i]]1 确定初始化&#xff1a;dp[0]0,其他的都…