rmw-shell
rmw-shell copied to clipboard
Profil Image sometimes turned by 90 degrees (Iphones)
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?
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))) ) ) `
Can you send a PR?