移动端手机h5上传图片旋转90度

移动端手机h5上传图片会旋转90度的问题

h5页面调用相机正常情况下都是正常的,但是有些手机横着照相的时候就会正常的,iphone正确的拍照方式是横屏的,而用户往往是竖屏拍照上传的,就相当于照相机反转了90度,当你横屏拍照上传,图片就是正确的,一张生成的图片是无法辨别方向的,就只有在上传之前反转了.

首先我们借助exif-js可以实现相机镜头的读取,不支持IE10以下,也可以直接引用的js文件,我使用npm安装依赖里面没有看到相关的js文件,就使用此办法.exif的部分文档API

//index.html引入js
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>

这个js文件暴露了一个EXIF的全局变量,我们可以把它挂在window对象上,使他变为一个全局变量

<script type="text/javascript">
    window.onload = function () {
      window.EXIF = EXIF
    }
</script>

然后在上传的file文件中获取相机方向,然后使用convas重绘图片并旋转角度就可以了,我再项目里面使用的是vant-ui

//html
<van-uploader
 :after-read="onRead"
 :before-read="beforeRead"
 v-model="fileList"
 accept='image/*'
 :max-count="2"/>
//js
methods: {
	dataURLtoFile (dataurl, filename) { // 将base64转换为文件
      let arr = dataurl.split(',')
      let mime = arr[0].match(/:(.*?);/)[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, {type: mime})
    },
    uploadImg (file) {
      let _this = this
      let index = this.fileList.length - 1
      /* eslint-disable */
      EXIF.getData(file, () => {
        let orientation = null // 相机方向
        let imgWidth = null // 图片宽度
        let imgHeight = null // 图片高度
        EXIF.getAllTags(file)
        orientation = EXIF.getTag(file, 'Orientation')
        imgWidth = EXIF.getTag(file, 'ImageWidth')
        imgHeight = EXIF.getTag(file, 'ImageHeight')
        if (orientation === 6) { // 等于6顺时针旋转90度,等于8需要逆时针旋转90度,等于3需要旋转180度
          let canvas = document.createElement('canvas')
          let context = canvas.getContext('2d')
          let img = new Image()
          let reader = new FileReader()
          reader.readAsDataURL(file)
          reader.onload = (e) => {
            img.src = e.target.result
            img.onload = () => {
              canvas.width = imgWidth
              canvas.height = imgHeight
              context.save() // 保存状态
              context.translate(canvas.width / 2, canvas.height / 2)
              context.rotate(90 * Math.PI / 180) // 旋转角度
              context.drawImage(img, -(canvas.height / 2), -(canvas.width / 2), canvas.height, canvas.width)
              context.restore() // 恢复状态
              let newImg = canvas.toDataURL('image/jpeg', 1)
              let files = _this.dataURLtoFile(newImg, file.name) // 将base64转为files文件
              let urlImg = window.URL.createObjectURL(files) // 将file转为临时url给组件回显
              this.$set(this.fileList, index, {url: urlImg, isImage: true})
              this.uploadImgAPI(files)
            }
          }
        } else { // 不需要旋转的直接上传
          this.uploadImgAPI(file)
        }
      })
    },
    uploadImgAPI (file) { // 上传图片接口
      const data = new FormData()
      data.append('file', file)
      data.append('code', this.applyNo)
      data.append('type', 'chat')
      apiUpload(data).then(res => {
        if (res.status === 200) {
          this.imagePath.push(res.data.reqUrl)
          Toast('上传成功')
        }
      }).catch(() => {
        this.fileList.pop()
      })
    }
}

将重绘的图片转为file文件传给后台,就OK了,其实在这之前还有一步压缩和检验格式的过程,在其他文章里面也写过

//js
method: {
	beforeRead (file) { // 检测文件大小
      let regex = /(.jpg|.jpeg|.png|.bmp)$/
      if (!regex.test(file.type)) {
        Toast('图片格式不支持上传')
        return false
      } else {
        return true
      }
    },
    onRead (file) { // 上传图片
      // 大于10MB的图片都缩小像素上传
      if (file.file.size > 10485760) {
        let canvas = document.createElement('canvas')
        let context = canvas.getContext('2d')
        let img = new Image()
        img.src = file.content // 指定图片的DataURL(图片的base64编码数据)
        img.onload = () => {
          canvas.width = 400 // 指定canvas画布大小,该大小为最后生成图片的大小
          canvas.height = 300 
          context.drawImage(img, 0, 0, 400, 300)
          file.content = canvas.toDataURL(file.file.type, 0.92) 
          let files = this.dataURLtoFile(file.content, file.file.name)
          this.uploadImg(files)
        }
      } else {
        this.uploadImg(file.file)
      }
    }
}

最终这样就好了.但是这样还有一个小问题需要优化的就是经过压缩之后的图片没有相机方向,需要在压缩的同时就需要旋转过来,大家可以尝试一下.

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用规范:  var file = $("#file_input")[0].files[0]; if(file.size / 1024 > 1024 * 5){ mui.toast('图片不能超过5M'); return; } //图片压缩 compress.rotatePhotoCompress(file,function(imageObj){ var formData = new FormData(); formData.append("uploadFile", imageObj, file.name); // 文件对象 //图片上传 uploadAdd(formData); }); /** * 图片上传 * @param formData */ function uploadAdd(formData){ var URL = apiUrl.addMultImageURL+"?plateTag=order&fileOwnerId=order&fileType=image&token;="+app.getToken(); $.ajax({ url: URL, //请求地址 type: "post", async: true, //默认为异步 data: formData, //参数 contentType: false, //数据请求格式 processData:false, xhr:function(){ myXhr = $.ajaxSettings.xhr(); if(myXhr.upload){ // check if upload property exists myXhr.upload.addEventListener('progress',function(e){ //显示进条 $("#progress1").show(); var loaded = e.loaded;//已经上传大小情况 var tot = e.total;//附件总大小 var per = Math.floor(100*loaded/tot); //已经上传的百分比 mui("#progress1").progressbar({progress:per}).show(); }, false); // for handling the progress of the upload } return myXhr; },// 成功 success: function (data) { //隐藏进条 $("#progress1").hide(); if (data.error == 0 && null != data.url) { mui.toast('上传图片成功'); $('.show_img').append("<div class='imgList'><span class='oClose'>X</span><img src="+app.fileUrl+data.url+"><input type='hidden' name='imgUrls["+count+"]' value="+data.url.replace(app.fileUrl,"")+"></div>"); count++; } else { mui.toast('上传图片失败'); $('#uploadPicButton').html('请你选择图片重新上传'); } }, error:function(rep) { $("#progress1").hide(); console.log(JSON.stringify(rep)); mui.toast('上传异常'); } }) }
H5移动端手机登录模板是一种在手机浏览器上运行的登录页面模板。它主要用于用户在手机上登录网站或应用程序,提供了简洁、直观的界面和交互方式。 H5移动端手机登录模板通常包含以下几个关键元素: 1. 登录表单:包括输入用户名和密码的文本框,以及登录按钮。用户可以在这里输入登录凭据,点击登录按钮后提交表单进行身份验证。 2. 注册链接:通常位于登录表单下方,提供一个快速注册的入口。用户可以点击该链接跳转到注册页面进行新用户注册。 3. 忘记密码链接:通常也位于登录表单下方,点击该链接后,用户可以跳转到找回密码的页面进行密码重置操作。 4. 社交媒体登录按钮:有些H5移动端手机登录模板还提供了通过社交媒体账号登录的选项,比如使用微信、QQ、微博等账号登录。用户可以点击相应的按钮,在授权后直接使用社交媒体账号登录。 另外,为了提升用户体验和安全性,H5移动端手机登录模板还可以包含以下功能或措施: 1. 验证码:在登录表单中加入验证码输入框,防止恶意程序和机器人攻击。 2. 手势密码:提供手势密码的登录方式,用户可以选择设置手势密码登录,提升登录的安全性。 3. 短信验证码登录:支持用户通过手机号码接收短信验证码进行登录,提高登录的安全性和便捷性。 总的来说,H5移动端手机登录模板是为了适应移动设备的特点而设计的登录界面模板,提供了简洁、易用的登录方式,并且可以根据实际需求扩展相应的功能和安全措施。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值