AlloyTeam / AlloyCrop

The best and tiny size mobile cropping component - 做最好且最小的移动裁剪组件
https://alloyteam.github.io/AlloyCrop/
943 stars 145 forks source link

在ios上图片旋转 #11

Open moshuchao opened 7 years ago

moshuchao commented 7 years ago

如果我使用拍照获得的图片作为image_src,预览的时候是正常的,但是裁剪出来的图片旋转了90度。

yuwengCipher commented 6 years ago

我也遇到这个问题,谁能来解决下 啊~~~~~

cat-kun commented 6 years ago

为什么裁剪出来的图片会旋转了90度

dntzhang commented 6 years ago

你们需要这个库 : https://github.com/exif-js/exif-js http://www.zixuephp.com/html/javascript/2016_07/42004.html

Dreammy23 commented 6 years ago

EXIF中的Orientation代表照片方向,有1—8八个值,ios竖着拍照Orientation=6,所以照片歪着,需要调整 EXIF.getData(this.file, function(){ let Orientation = EXIF.getTag(this, 'Orientation'); //针对各种情况分别调整 switch(Orientation){ case'2': . . . case'8': } }

dongnaebi commented 6 years ago

写了个压缩/旋转类,可以参考下

import EXIF from 'exif-js'
class ImageFile {
  dataURLtoBlob (dataURL = '') {
    let arr = dataURL.split(',')
    let mime = arr[0].match(/:(.*?);/)[1]
    let bstr = window.atob(arr[1])
    let n = bstr.length
    let u8arr = new Uint8Array(n)
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n)
    }
    return new window.Blob([u8arr], {type: mime})
  }
  orientation (file = null) {
    return new Promise((resolve, reject) => {
      EXIF.getData(file, function () {
        const orientation = EXIF.getTag(this, 'Orientation')
        resolve(orientation)
      })
    })
  }
  toDataURL (file = null) {
    const fr = new window.FileReader()
    fr.readAsDataURL(file)
    return new Promise((resolve, reject) => {
      fr.onload = (f) => {
        resolve(f.target.result)
      }
    })
  }
  compress ({file = null, maxWidth = 1000, maxHeight = 1000, ratio = 1}) {
    const self = this
    let img = document.createElement('img')
    let canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    self.toDataURL(file).then(base64 => {
      img.src = base64
    })
    return new Promise((resolve, reject) => {
      img.onload = async () => {
        const orientation = await self.orientation(file)
        const originWidth = img.width
        const originHeight = img.height

        let targetWidth = originWidth
        let targetHeight = originHeight
        if (originWidth > maxWidth || originHeight > maxHeight) {
          if (originWidth / originHeight > maxWidth / maxHeight) {
            targetWidth = maxWidth
            targetHeight = Math.round(maxWidth * (originHeight / originWidth))
          } else {
            targetHeight = maxHeight
            targetWidth = Math.round(maxHeight * (originWidth / originHeight))
          }
        }
        canvas.width = targetWidth
        canvas.height = targetHeight
        if (orientation && orientation !== 1) {
          switch (orientation) {
            case 6:
              canvas.width = targetHeight
              canvas.height = targetWidth
              ctx.rotate(Math.PI / 2)
              ctx.drawImage(img, 0, -targetHeight, targetWidth, targetHeight)
              break
            case 3:
              ctx.rotate(Math.PI)
              ctx.drawImage(img, -targetWidth, -targetHeight, targetWidth, targetHeight)
              break
            case 8:
              canvas.width = targetHeight
              canvas.height = targetWidth
              ctx.rotate(3 * Math.PI / 2)
              ctx.drawImage(img, -targetWidth, 0, targetWidth, targetHeight)
              break
          }
        } else {
          ctx.drawImage(img, 0, 0, targetWidth, targetHeight)
        }

        let dataURL = canvas.toDataURL(file.type, ratio)
        let blob = await self.dataURLtoBlob(dataURL)
        img = null
        canvas = null // 释放内存
        resolve({dataURL, blob})
      }
    })
  }
}
export default ImageFile
MicroJes commented 6 years ago

重置图片方法 做一个转换

function resetOrientation(srcBase64, srcOrientation, callback) {
    var img = new Image();

    img.onload = function() {
        var width = img.width,
            height = img.height,
            canvas = document.createElement('canvas'),
            ctx = canvas.getContext("2d");

        // set proper canvas dimensions before transform & export
        if (4 < srcOrientation && srcOrientation < 9) {
            canvas.width = height;
            canvas.height = width;
        } else {
            canvas.width = width;
            canvas.height = height;
        }

        // transform context before drawing image
        switch (srcOrientation) {
            case 2:
                ctx.transform(-1, 0, 0, 1, width, 0);
                break;
            case 3:
                ctx.transform(-1, 0, 0, -1, width, height);
                break;
            case 4:
                ctx.transform(1, 0, 0, -1, 0, height);
                break;
            case 5:
                ctx.transform(0, 1, 1, 0, 0, 0);
                break;
            case 6:
                ctx.transform(0, 1, -1, 0, height, 0);
                break;
            case 7:
                ctx.transform(0, -1, -1, 0, height, width);
                break;
            case 8:
                ctx.transform(0, -1, 1, 0, 0, width);
                break;
            default:
                break;
        }

        // draw image
        ctx.drawImage(img, 0, 0);

        // export base64
        callback(canvas);
    };

    img.src = srcBase64;
}