Implement client-size image resizing from upstream
This commit is contained in:
		
							parent
							
								
									d253449ff0
								
							
						
					
					
						commit
						c2e528916c
					
				| @ -3,6 +3,7 @@ import { CancelToken } from 'axios'; | ||||
| import { throttle } from 'lodash'; | ||||
| import { search as emojiSearch } from 'flavours/glitch/util/emoji/emoji_mart_search_light'; | ||||
| import { useEmoji } from './emojis'; | ||||
| import resizeImage from 'flavours/glitch/util/resize_image'; | ||||
| 
 | ||||
| import { | ||||
|   updateTimeline, | ||||
| @ -207,18 +208,14 @@ export function uploadCompose(files) { | ||||
| 
 | ||||
|     dispatch(uploadComposeRequest()); | ||||
| 
 | ||||
|     let data = new FormData(); | ||||
|     data.append('file', files[0]); | ||||
|     resizeImage(files[0]).then(file => { | ||||
|       const data = new FormData(); | ||||
|       data.append('file', file); | ||||
| 
 | ||||
|     api(getState).post('/api/v1/media', data, { | ||||
|       onUploadProgress: function (e) { | ||||
|         dispatch(uploadComposeProgress(e.loaded, e.total)); | ||||
|       }, | ||||
|     }).then(function (response) { | ||||
|       dispatch(uploadComposeSuccess(response.data)); | ||||
|     }).catch(function (error) { | ||||
|       dispatch(uploadComposeFail(error)); | ||||
|     }); | ||||
|       return api(getState).post('/api/v1/media', data, { | ||||
|         onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)), | ||||
|       }).then(({ data }) => dispatch(uploadComposeSuccess(data))); | ||||
|     }).catch(error => dispatch(uploadComposeFail(error))); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										116
									
								
								app/javascript/flavours/glitch/util/resize_image.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								app/javascript/flavours/glitch/util/resize_image.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| import EXIF from 'exif-js'; | ||||
| 
 | ||||
| const MAX_IMAGE_DIMENSION = 1280; | ||||
| 
 | ||||
| const getImageUrl = inputFile => new Promise((resolve, reject) => { | ||||
|   if (window.URL && URL.createObjectURL) { | ||||
|     try { | ||||
|       resolve(URL.createObjectURL(inputFile)); | ||||
|     } catch (error) { | ||||
|       reject(error); | ||||
|     } | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   const reader = new FileReader(); | ||||
|   reader.onerror = (...args) => reject(...args); | ||||
|   reader.onload  = ({ target }) => resolve(target.result); | ||||
| 
 | ||||
|   reader.readAsDataURL(inputFile); | ||||
| }); | ||||
| 
 | ||||
| const loadImage = inputFile => new Promise((resolve, reject) => { | ||||
|   getImageUrl(inputFile).then(url => { | ||||
|     const img = new Image(); | ||||
| 
 | ||||
|     img.onerror = (...args) => reject(...args); | ||||
|     img.onload  = () => resolve(img); | ||||
| 
 | ||||
|     img.src = url; | ||||
|   }).catch(reject); | ||||
| }); | ||||
| 
 | ||||
| const getOrientation = (img, type = 'image/png') => new Promise(resolve => { | ||||
|   if (type !== 'image/jpeg') { | ||||
|     resolve(1); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   EXIF.getData(img, () => { | ||||
|     const orientation = EXIF.getTag(img, 'Orientation'); | ||||
|     resolve(orientation); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| const processImage = (img, { width, height, orientation, type = 'image/png' }) => new Promise(resolve => { | ||||
|   const canvas  = document.createElement('canvas'); | ||||
| 
 | ||||
|   if (4 < orientation && orientation < 9) { | ||||
|     canvas.width  = height; | ||||
|     canvas.height = width; | ||||
|   } else { | ||||
|     canvas.width  = width; | ||||
|     canvas.height = height; | ||||
|   } | ||||
| 
 | ||||
|   const context = canvas.getContext('2d'); | ||||
| 
 | ||||
|   switch (orientation) { | ||||
|   case 2: context.transform(-1, 0, 0, 1, width, 0); break; | ||||
|   case 3: context.transform(-1, 0, 0, -1, width, height); break; | ||||
|   case 4: context.transform(1, 0, 0, -1, 0, height); break; | ||||
|   case 5: context.transform(0, 1, 1, 0, 0, 0); break; | ||||
|   case 6: context.transform(0, 1, -1, 0, height, 0); break; | ||||
|   case 7: context.transform(0, -1, -1, 0, height, width); break; | ||||
|   case 8: context.transform(0, -1, 1, 0, 0, width); break; | ||||
|   } | ||||
| 
 | ||||
|   context.drawImage(img, 0, 0, width, height); | ||||
| 
 | ||||
|   canvas.toBlob(resolve, type); | ||||
| }); | ||||
| 
 | ||||
| const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) => { | ||||
|   const { width, height } = img; | ||||
| 
 | ||||
|   let newWidth, newHeight; | ||||
| 
 | ||||
|   if (width > height) { | ||||
|     newHeight = height * MAX_IMAGE_DIMENSION / width; | ||||
|     newWidth  = MAX_IMAGE_DIMENSION; | ||||
|   } else if (height > width) { | ||||
|     newWidth  = width * MAX_IMAGE_DIMENSION / height; | ||||
|     newHeight = MAX_IMAGE_DIMENSION; | ||||
|   } else { | ||||
|     newWidth  = MAX_IMAGE_DIMENSION; | ||||
|     newHeight = MAX_IMAGE_DIMENSION; | ||||
|   } | ||||
| 
 | ||||
|   getOrientation(img, type) | ||||
|     .then(orientation => processImage(img, { | ||||
|       width: newWidth, | ||||
|       height: newHeight, | ||||
|       orientation, | ||||
|       type, | ||||
|     })) | ||||
|     .then(resolve) | ||||
|     .catch(reject); | ||||
| }); | ||||
| 
 | ||||
| export default inputFile => new Promise((resolve, reject) => { | ||||
|   if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') { | ||||
|     resolve(inputFile); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   loadImage(inputFile).then(img => { | ||||
|     if (img.width < MAX_IMAGE_DIMENSION && img.height < MAX_IMAGE_DIMENSION) { | ||||
|       resolve(inputFile); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     resizeImage(img, inputFile.type) | ||||
|       .then(resolve) | ||||
|       .catch(() => resolve(inputFile)); | ||||
|   }).catch(reject); | ||||
| }); | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user