亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Yup 和 formik 驗證圖像的縱橫比(寬度/高度)

使用 Yup 和 formik 驗證圖像的縱橫比(寬度/高度)

POPMUISE 2023-09-07 16:53:21
我正在嘗試使用 yup 對圖像文件進行驗證,我發現https://github.com/formium/formik/issues/926只驗證大小和文件類型。這是我當前使用的 yup 驗證file: lazy(value => {    switch (typeof value) {      case 'string':        return string().required(errorHandler.requiredFile());      default:        return mixed()          .required(errorHandler.requiredFile())          .test(            'fileSize',            'Size',            value => value && value.size <= FILE_SIZE          )          .test(            'fileType',            'Format',            value => value && SUPPORTED_FORMATS.includes(value.type)          )    }  }),我該怎么做?
查看完整描述

4 回答

?
米脂

TA貢獻1836條經驗 獲得超3個贊

創建一個將加載圖像文件并返回尺寸的承諾

const imageWidthAndHeight = (provideFile) => {

    // take the given file (which should be an image) and return the width and height

    const imgDimensions = { width: null, height: null };


    return new Promise(resolve => {

        const reader = new FileReader();

        

        reader.readAsDataURL(provideFile);

        reader.onload = function () {

            const img = new Image();

            img.src = reader.result;


            img.onload = function () {

                imgDimensions.width = img.width;

                imgDimensions.height = img.height;


                resolve(imgDimensions);

            }

        };

    });

}

在自定義 yup 函數中調用并等待 Promise(使用 addMethod),并添加額外的驗證來檢查寬度和高度。

const imageDimensionCheck = Yup.addMethod(Yup.mixed, 'imageDimensionCheck', function (message, requiredWidth, requiredHeight) {

    return this.test("image-width-height-check", message, async function (value) {

        const { path, createError } = this;


        if (!value) {

            return;

        }


        const imgDimensions = await imageWidthAndHeight(value);


        if (imgDimensions.width !== requiredWidth) {

            return createError({

                path,

                message: `The file width needs to be the ${requiredWidth}px!`

              });

        }


        if (imgDimensions.height !== requiredHeight) {

            return createError({

                path,

                message: `The file height needs to be the ${requiredHeight}px!`

              });

        }


        return true;

    });

});

在formik中調用創建的Yup方法

<Formik

    initialValues={{

        bookCoverPhoto: null,

    }}


    validationSchema={

        Yup.object().shape({

            bookCoverPhoto: Yup.mixed()

                .required('You need to provide a file')

                .imageDimensionCheck('test', 1988, 3056)

        })

    }

>

....Stuff

</Formik>


查看完整回答
反對 回復 2023-09-07
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

這里有兩種替代方法,它們比 Base64 編碼(解碼)更快,并且不需要文件讀取器


function checkAspectRatio (file) {

    const img = new Image()

    img.src = URL.createObjectURL(file)

    return img.decode().then(() => {

        URL.revokeObjectURL(img.src)

        return img.width / img.height

    })

}


// not as cross compatible

function checkAspectRatio (file) {

    return createImageBitmap(file)

      .then(bitmap => bitmap.width / bitmap.height)

}


查看完整回答
反對 回復 2023-09-07
?
夢里花落0921

TA貢獻1772條經驗 獲得超6個贊

image: Yup.mixed()

  .required("Image is required.")

  .test(

    "aspectRatio",

    "Aspect ratio must be 16:9",

    value => {

      return new Promise(resolve => {

        const reader = new FileReader();

        reader.readAsDataURL(value[0]);

        reader.onload = function(value) {

          const img = new Image();

          img.src = value.target.result;

          img.onload = function() {

            const aspectRatio = this.width / this.height;

            resolve(aspectRatio === (16 / 9));

          };

        };

      });

    }

  ),


查看完整回答
反對 回復 2023-09-07
?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

我設法使用這個功能來做到這一點


function checkAspectRatio(value) {

  return new Promise(resolve => {

    const reader = new FileReader();

    reader.readAsDataURL(value);

    reader.onload = function(value) {

      const img = new Image();

      img.src = value.target.result;

      img.onload = function() {

        const aspectRatio = this.width / this.height;

        resolve(aspectRatio);

      };

    };

  });

}


用于Object.defineProperty()在對象上定義新屬性


Object.defineProperty(file, 'aspectRatio', {

  value: await checkAspectRatio(file)

});


并使用 yup 測試該值


.test(

  'fileAspectRatio',

  'Please recheck the image resolution',

  value => value && value.aspectRatio === 1.6

);


查看完整回答
反對 回復 2023-09-07
  • 4 回答
  • 0 關注
  • 175 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號