rmw-shell icon indicating copy to clipboard operation
rmw-shell copied to clipboard

Profil Image sometimes turned by 90 degrees (Iphones)

Open wortkotze opened this issue 5 years ago • 2 comments

We encounter some issues that the profil picture is uploaded with 90 degree turn. We checked the EXIF Information of the uploaded pictures but it doesn't show anything that u need to turn the image ...

any idea?

wortkotze avatar Jun 02 '19 02:06 wortkotze

We fixed the issue with the following fix for ImageCropper Component

`import 'firebase/storage' import Button from '@material-ui/core/Button' import CircularProgress from '@material-ui/core/CircularProgress' import Dialog from '@material-ui/core/Dialog' import DialogActions from '@material-ui/core/DialogActions' import DialogContent from '@material-ui/core/DialogContent' import DialogTitle from '@material-ui/core/DialogTitle' import LinearProgress from '@material-ui/core/LinearProgress' import PropTypes from 'prop-types' import React, { Component } from 'react' import firebase from 'firebase/app' import withMobileDialog from '@material-ui/core/withMobileDialog' import { connect } from 'react-redux' import { injectIntl, intlShape } from 'react-intl' import { withFirebase } from 'firekit-provider' import AvatarEditor from 'react-avatar-editor' import classNames from 'classnames' import { withStyles } from '@material-ui/core/styles'

var EXIF = require('exif-js')

const styles = theme => ({ ctaInput: { opacity: 0 }, ctaMainBlack: { background: '#000', border: '1px solid #000', borderRadius: '0px', textTransform: 'none', color: '#FFF', height: '50px', padding: '0 30px', fontFamily: 'AudiType, sans-serif', width: '100%', boxShadow: '0px 0px 0px 0px', marginTop: '10px',

'&:active': {
  background: '#000'
},

'&:hover': {
  background: '#000'
}

},

ctaMainWhite: { background: '#FFF', border: '1px solid #000', borderRadius: '0px', textTransform: 'none', color: '#000', height: '50px', padding: '0 30px', fontFamily: 'AudiType, sans-serif', boxShadow: '0px 0px 0px 0px', width: '100%',

'&:active': {
  background: '#000'
},

'&:hover': {
  background: '#FFF'
}

},

container: { display: 'flex', alignItems: 'stretch', justifyContent: 'center', flexDirection: 'row', background: '#fff' }, dialog: { width: '100%', maxWidth: 'none', background: '#fff' }, cropper: { height: 250, width: 250, background: '#fff' }, flexparent: { display: 'flex', flexDirection: 'column', flexWrap: 'nowrap', justifyContent: 'space-between', width: '100%' },

flexchild: {} })

export class ImageCropDialog extends Component { constructor(props) { super(props) this.state = { src: undefined, isLoading: false, isUploading: false, uploadProgress: 0, rotate: 0 } }

handlePhotoURLUpload = photo_url => { const { classes, path, fileName, onUploadSuccess, firebaseApp } = this.props

this.setState({ isUploading: true, uploadProgress: 0 })

let uploadTask = firebaseApp
  .storage()
  .ref(`${path}/${fileName}`)
  .putString(photo_url, 'data_url')

uploadTask.on(
  firebase.storage.TaskEvent.STATE_CHANGED,
  snapshot => {
    let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
    this.setState({ isUploading: true, uploadProgress: progress })
  },
  error => {
    console.log(error)
  },
  () => {
    this.setState({ isUploading: false, uploadProgress: 100 }, () => {
      onUploadSuccess(uploadTask.snapshot)
    })
  }
)

}

handlePhotoULRChange = e => { e.preventDefault()

this.setState({ isLoading: true })

let files
if (e.dataTransfer) {
  files = e.dataTransfer.files
} else if (e.target) {
  files = e.target.files
}
const reader = new FileReader()
reader.onload = () => {
  this.setState({ src: reader.result, isLoading: false, file: files[0] })
}
reader.readAsDataURL(files[0])
var that = this
EXIF.getData(e.target.files[0], function() {
  var make = EXIF.getTag(this, 'Make')
  var model = EXIF.getTag(this, 'Model')
  var orientation = EXIF.getTag(this, 'Orientation')
  let rotatePic = 0
  switch (orientation) {
  case 8:
    rotatePic = 270
    break
  case 6:
    rotatePic = 90
    break
  case 3:
    rotatePic = 180
    break
  default:
    rotatePic = 0
  }
  that.setState({ rotate: rotatePic })
})

}

handleClose = () => { const { handleClose } = this.props this.setState({ src: undefined }) handleClose() }

setEditorRef = editor => (this.editor = editor)

render() { const { intl, open, title, fullScreen, classes } = this.props

const actions = [
  <Button
    disabled={
      !this.state.src || this.state.isLoading || this.state.isUploading
    }
    label={intl.formatMessage({ id: 'submit' })}
    primary={true}
    onClick={() => {
      this.handlePhotoURLUpload(this.editor.getImage().toDataURL())
    }}
  />,
  <Button
    label={intl.formatMessage({ id: 'cancel' })}
    secondary={true}
    onClick={this.handleClose}
  />
]

return (
  <Dialog
    fullScreen={fullScreen}
    open={open}
    onClose={this.handleClose}
    aria-labelledby="responsive-dialog-title"
    className={styles.dialog}>
    <DialogTitle id="responsive-dialog-title">{title}</DialogTitle>

    <DialogContent>
      <div style={styles.container}>
        <div style={styles.cropper}>
          {(!this.state.src || this.state.isLoading) && (
            <div>
              <Button color="primary" className={classes.ctaMainBlack}>
                Upload Image
              </Button>
              <input
                ref={field => {
                  if (field !== null) {
                    field.click()
                  }
                }}
                type="file"
                accept="image/*"
                //style={{visibility:'hidden'}}
                onChange={this.handlePhotoULRChange}
                className={classes.ctaInput}
              />
            </div>
          )}

          {this.state.isLoading && (
            <CircularProgress size={80} thickness={5} />
          )}

          {this.state.isUploading && (
            <LinearProgress
              mode="determinate"
              value={this.state.uploadProgress}
            />
          )}

          {this.state.src && (
            <center>
              <AvatarEditor
                ref={this.setEditorRef}
                image={this.state ? this.state.src : undefined}
                width={200}
                height={200}
                border={25}
                color={[255, 255, 255, 0.6]}
                scale={1.0}
                rotate={this.state.rotate}
              />
            </center>
          )}
        </div>
      </div>
    </DialogContent>
    <DialogActions>
      <div className={classes.flexparent}>
        <div className={classes.flexchild}>
          <Button
            color="primary"
            onClick={this.handleClose}
            className={classes.ctaMainWhite}>
            {intl.formatMessage({ id: 'cancel' })}
          </Button>
        </div>

        <div className={classes.flexchild}>
          <Button
            color="primary"
            autoFocus
            onClick={() =>
              this.handlePhotoURLUpload(this.editor.getImage().toDataURL())
            }
            className={classes.ctaMainBlack}>
            {intl.formatMessage({ id: 'submit' })}
          </Button>
        </div>
      </div>
    </DialogActions>
  </Dialog>
)

} }

ImageCropDialog.propTypes = { intl: intlShape.isRequired, open: PropTypes.bool.isRequired, title: PropTypes.string, path: PropTypes.string.isRequired, fileName: PropTypes.string.isRequired, onUploadSuccess: PropTypes.func.isRequired, handleClose: PropTypes.func.isRequired }

const mapStateToProps = state => { const { auth } = state return { auth } }

export default connect( mapStateToProps, {} )( injectIntl( withStyles(styles)(withFirebase(withMobileDialog()(ImageCropDialog))) ) ) `

wortkotze avatar Aug 15 '19 10:08 wortkotze

Can you send a PR?

TarikHuber avatar Aug 16 '19 07:08 TarikHuber