Next.js and sharp implement placeholder image generation tool

Placeholder Image is a commonly used tool in front-end development. It is used to provide placeholders for image elements when the web page loads slowly or does not load completely. However, sometimes we need a more flexible way to generate custom placeholder images to meet specific needs. In this blog, we will introduce how to use the Next.js and sharp frameworks to implement a placeholder image generation tool, allowing you to generate custom placeholders as needed picture.

Placeholder image generation tool

  • Link: https://next-blog.tiven.cn/api/g/400/200, the display effect is as above
  • Usage documentation: Custom placeholder image generation tool usage documentation

1. The role of placeholder image generation tool

The placeholder image generation tool is an application used to dynamically generate placeholder images. Its functions are as follows:

effect:

  1. Custom placeholder image generation: With this tool, you can generate various custom placeholder images according to your needs. These images can include different sizes, colors, text content, and styles.
  2. Improve development efficiency: In front-end development, it is often necessary to use placeholder images to display image placeholders, and manually creating these placeholder images is cumbersome. Placeholder image generation tools can greatly improve development efficiency.
  3. Support different formats: This tool supports generating placeholder images in SVG and PNG formats to suit different project needs.

2. Usage scenarios

  1. Website Development: In website development, placeholder images are used to occupy the position of image elements to provide visual feedback when the image loads. The generation tool can generate placeholder images that meet size and color requirements based on the web page layout.
  2. Mobile application development: Mobile applications usually contain a lot of image elements, and using placeholder images can improve the loading speed and performance of the application. The generation tool generates compliant placeholder images for mobile apps.
  3. Designer collaboration: Placeholder image generation tools can also work between designers and developers. Designers can use tools to generate placeholder images to occupy empty image areas in a design to better demonstrate design intent.
  4. Custom test data: During development and testing, you can use placeholder images as test data to ensure that the application handles image elements correctly.

3. Implement placeholder image generation tool

The following is a sample code for a placeholder image generation tool based on the Next.js framework and the sharp image processing library. You can run this example locally to better understand how to implement the placeholder image generator.

Step 1: Create Next.js project

First, let’s create a Next.js project to start building our placeholder image generation tool. Initialize a new project using the following command:

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

Step 2: Set up API routing

In Next.js, we can use API routing to create server-side endpoints. We will create an API route that will handle the request to generate the placeholder image. Create a file called pages/api/g/[...px].js in the project root directory. This will be the entry point for our build tool.

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

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

export default async function handler(req, res) {<!-- -->
  try {<!-- -->
    // Parse request parameters
    let {<!-- --> px, text, bg, color, size, type } = req.query;

    // Process parameters and set default values
    let [w, h] = px?.length >= 2 ? px : [200, 200];
    text = text || `${<!-- -->w} x ${<!-- -->h}`;
    bg = bg || 'ccc';
    color = color || '666';
    size = size || 32;

    // Handle color parameters
    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';

    // Generate SVG image
    let ratio = 1;
    let buffer = getSvgBuffer({<!-- -->
      w: ratio * w,
      h: ratio * h,
      bg: bgStr,
      color: colorStr,
      size,
      text,
    });

    //Respond to images in different formats based on type
    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());
  }
}

Step 3: Function to generate SVG image

We used a function named getSvgBuffer in the above code to generate SVG images. This function accepts parameters, including width, height, background color, text color, text content and text size.

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',\ 'Heidi','STXingkai';"
    fill-opacity="1">${<!-- -->text}</text>
  </svg>`;
  return Buffer.from(svg);
}

Step 4: Handle error conditions

In the above code, we use the getErrorHtml function to generate an HTML page containing error information. This is a simple HTML template used to provide error information to the user when an error occurs.

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="/">← Return to homepage</a>`
      : ''
  return `
    <head>
      <link rel="icon" href="${<!-- -->basePath}/favicon.ico">
      <title>Customized placeholder image</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 address exception
        ${<!-- -->backHome}
      </h1>
      <p>The URL format reference is as follows:</p>
      <ol>
      <li>
        Default: <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 placeholder image: <a href="${<!-- -->publicPath}/200/100?type=svg & amp;bg=FEDC9B">${<!-- -->publicPath} /200/100?type=svg & amp;bg=FEDC9B</a>
        <br>
        <img style="width: 200px; height: 100px" class="img" src="${<!-- -->publicPath}/200/100?type=svg & amp;bg= FEDC9B" alt="tiven-img">
      </li>
      <li>
        Custom size: <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>
        Custom content: <a href="${<!-- -->publicPath}/400/200?bg=palevioletred & amp;color=purple & amp;text=React & amp;size=30"> ${<!-- -->publicPath}/400/200?bg=palevioletred & amp;color=purple & amp;text=React & amp;size=30</a>
        <br>
        <img style="width: 400px; height: 200px" class="img" src="${<!-- -->publicPath}/400/200?bg=palevioletred & amp;color= purple & amp;text=React & amp;size=30" alt="tiven-img">
      </li>
      </ol>
      <table border="1" borderColor="#ddd">
      <tr>
      <th>Parameters (optional)</th>
      <th>Function</th>
      </tr>
      <tr>
      <td>bg</td>
      <td>Background color, default: <code>#ccc</code></td>
      </tr>
      <tr>
      <td>color</td>
      <td>Text color, default: <code>#666</code></td>
      </tr>
      <tr>
      <td>text</td>
      <td>Text, default: <code>200x200</code> (width x height)</td>
      </tr>
      <tr>
      <td>size</td>
      <td>Text size, default: <code>32</code></td>
      </tr>
      <tr>
      <td>type</td>
      <td>Placement image type, default: <code>png</code>, optional svg</td>
      </tr>
      </table>
      <p><b>bg</b>, <b>color</b> color parameters can pass the value of <u>hex type</u>: <code>50A6EE</code>, <code>f00</code> ;</p>
      <p>You can also pass <u>English words</u> that represent colors: <code>red</code>, <code>pink</code>, <code>red</code>, etc.</p>
      <p style="font-size: 20px;">Complete technical implementation blog:<a href="https://tiven.cn/p/aa610ce5/" target="_blank" title=\ "Next.js and sharp implement a placeholder image generation tool">Next.js and sharp implement a placeholder image generation tool</a></p>
    </div>
    `
}

Step 5: Run and test

Now, you can launch your Next.js application and test the placeholder image generator. Run the following command:

npm run dev

Then, visit http://localhost:3000/api/g/400/200 in the browser and try different parameter combinations to generate a customized placeholder image.

4. Summary

In this blog, we take a deep dive into how to create a placeholder image generator using the Next.js framework and the sharp image processing library. This tool allows you to generate custom placeholder images based on user parameters, which is very suitable for image placeholder needs in front-end development. With this example, you can learn how to set up API routing, handle request parameters, generate SVG images, and handle error conditions. This will make you more flexible in front-end development to meet the needs of different projects. Whether it is website development, mobile app development or collaboration between designers and developers, placeholder image generation tools can increase work efficiency and improve user experience.

Welcome to: Tianwen Blog