js实现图片像素验证

1,024 阅读1分钟

image.png

前言

  • 在一些特定的项目中,会碰到关于图片上传的需求,且对 图片像素 存在固定值的要求,像素必须等于某个固定值

实现代码

  • 通过 html5的 FileReader api来完成 图片的上传数据 解析
  • 解析完成后,得到 img 进行图片像素验证,实例化 Image,并对 src 进行赋值,赋值内容为 解析成功的文件流信息,通过 onload 事件来判断图片是否 加载完成
  • 加载完成后,使用 reject、resolve 来表示是否已进行验证,成功后使用 Promise.then() 的方式,完成后续操作(例:文件上传)
/**
 * 上传的图片像素校验
 * @param {blob} file: 上传的图片文件
 * @param {number} imgWidth: 图片宽度
 * @param {number} imgHeight: 图片高度
 * @returns {boolean|Promise} 验证结果
 */
function imgPixelVerification (file, imgWidth, imgHeight) {
  if (!file || !imgWidth || !imgHeight) return false

  return new Promise((resolve, reject) => {
    // 调用api并进行实例化,完成 文件解析
    const reader = new FileReader()
    // 解析完成,e: 解析结果
    reader.onload = e => {
      const data = e.target.result
      // 实例化Image,用于获取图片真实宽度和高度
      const image = new Image()
      // 文件加载完毕
      image.onload = () => {
        const currentImagewidth = image.width
        const currentImageheigth = image.height
        // 图片 宽度、高度 验证
        if (currentImagewidth !== imgWidth || currentImageheigth !== imgHeight) {
          reject()
        } else {
          resolve()
        }
      }
      // 赋值实例化的 img文件流
      image.src = data
    }
    // 文件开始解析,参数: 解析文件
    reader.readAsDataURL(file)
  })
}

调用实例

<body>
    <input id="upload-file" type="file" onChange="handleUploadFileChange()" />
    <script>
      // 允许上传的图片格式
      const isAllowedImageUploadFormats = ["jpg", "jpeg", "png"];

      /**
       * 上传的文件内容发生改变
       */
      function handleUploadFileChange() {
        const uploadInput = document.querySelector("#upload-file");
        // 获取 input 上传文件列表
        const uploadFiles = uploadInput.files && [...uploadInput.files];
        if (!uploadFiles[0]) return;
        // 上传文件格式验证
        if (
          !isAllowedImageUploadFormats.includes(
            uploadFiles[0].name.substring(
              uploadFiles[0].name.lastIndexOf(".") + 1
            )
          )
        ) {
          alert("当前仅支持上传" + isAllowedImageUploadFormats.join(", "));
          return;
        }
        // 上传图片需要的像素大小
        const imgWidth = 600;
        const imgHeight = 400;
        // 调用函数,图片像素大小验证
        const verificationResult = imgPixelVerification(
          uploadFiles[0],
          imgWidth,
          imgHeight
        );
        verificationResult &&
          verificationResult
            .then(() => {
              // 请求,文件上传
              uploadFile(uploadFiles[0]).then((uploadFileInfo) => {
                // 文件上传后的相关业务代码
              });
            })
            .catch(() => {
              alert("图片像素必须为 " + imgWidth + "x" + imgHeight);
            });
      }
    </script>
  </body>

完整实例

  • 支持 本地预览
  • 支持 文件格式验证
  • 支持 像素验证
  • 需要支持更多的验证,可在 handleUploadFileChange 进行新增
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        width: 100vw;
        height: 100vh;
        padding: 0;
        margin: 0;
      }

      body .content-wrap {
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }

      body .content-wrap #upload-file {
        margin-top: 1vh;
      }
    </style>
  </head>

  <body>
    <div class="content-wrap">
      <!-- 本地预览 -->
      <img id="preview-img" width="500" height="300" />
      <!-- 文件上传 -->
      <input id="upload-file" type="file" onChange="handleUploadFileChange()" />
    </div>
    <script>
      // 允许上传的图片格式
      const isAllowedImageUploadFormats = ["jpg", "jpeg", "png"];

      /**
       * 上传的文件内容发生改变
       */
      function handleUploadFileChange() {
        const uploadInput = document.querySelector("#upload-file");
        // 获取 input 上传文件列表
        const uploadFiles = uploadInput.files && [...uploadInput.files];
        if (!uploadFiles[0]) return;
        // 上传文件格式验证
        if (
          !isAllowedImageUploadFormats.includes(
            uploadFiles[0].name.substring(
              uploadFiles[0].name.lastIndexOf(".") + 1
            )
          )
        ) {
          alert("当前仅支持上传" + isAllowedImageUploadFormats.join(", "));
          return;
        }
        // 上传图片需要的像素大小
        const imgWidth = 600;
        const imgHeight = 400;
        // 调用函数,图片像素大小验证
        const verificationResult = imgPixelVerification(
          uploadFiles[0],
          imgWidth,
          imgHeight
        );
        verificationResult &&
          verificationResult
            .then(() => {
              // 请求,文件上传
              uploadFile(uploadFiles[0]).then((uploadFileInfo) => {
                // 文件上传后的相关业务代码
              });
            })
            .catch(() => {
              alert("图片像素必须为 " + imgWidth + "x" + imgHeight);
            });
      }

      /**
       * 上传的图片像素校验
       * @param {blob} file: 上传的图片文件
       * @param {number} imgWidth: 图片宽度
       * @param {number} imgHeight: 图片高度
       * @returns {boolean|Promise} 验证结果
       */
      function imgPixelVerification(file, imgWidth, imgHeight) {
        if (!file || !imgWidth || !imgHeight) return false;

        return new Promise((resolve, reject) => {
          // 调用api并进行实例化,完成 文件解析
          const reader = new FileReader();
          // 解析完成,e: 解析结果
          reader.onload = (e) => {
            const data = e.target.result;
            // 实例化Image,用于获取图片真实宽度和高度
            const image = new Image();
            // 文件加载完毕
            image.onload = () => {
              const currentImagewidth = image.width;
              const currentImageheigth = image.height;
              // 图片 宽度、高度 验证
              if (
                currentImagewidth !== imgWidth ||
                currentImageheigth !== imgHeight
              ) {
                reject();
              } else {
                // 本地预览上传图片
                document.querySelector("#preview-img").src = data;
                resolve();
              }
            };
            // 赋值实例化的 img文件流
            image.src = data;
          };
          // 文件开始解析,参数: 解析文件
          reader.readAsDataURL(file);
        });
      }
    </script>
  </body>
</html>

写在最后

如有问题,欢迎指教,共同学习