Dosya boyutunun küçültülmesine yardımcı olan yollardan biri, kullanıcıların resimlerini kırpmalarına ve ardından Firebase Depolamama yüklenmeden önce yeniden boyutlandırmalarına izin vermektir. React-easy-crop kitaplığını kullanarak temel görüntü kırpmayı nasıl yapıldığını anlatacağım.
1. Aşama : React-easy-crop yükleyin;
npm install react-easy-crop --save
2. Aşama : ImageCropper bileşenini kurun.
getBlob()
, Kırpılan resmi bu alt bileşenden geçirmek için kullanıyorum.
Ayar aspect={1}
, görüntünün bir kareye kırpılmasına neden olur, ancak en boy oranını istediğiniz şekilde değiştirebilirsiniz. Benim için, en boy oranını uygulamamdaki kullanıcı avatarları için kullandığım için 1 olarak tuttum çünkü kare resimlerin stilini ayarlamak daha kolay.
// ImageCropper.js
import React, { useState } from 'react'
import Cropper from 'react-easy-crop'
import { getCroppedImg } from './cropImage'
const ImageCropper = ({ getBlob, inputImg }) => {
const [crop, setCrop] = useState({ x: 0, y: 0 })
const [zoom, setZoom] = useState(1)
/* onCropComplete() will occur each time the user modifies the cropped area,
which isn't ideal. A better implementation would be getting the blob
only when the user hits the submit button, but this works for now */
const onCropComplete = async (_, croppedAreaPixels) => {
const croppedImage = await getCroppedImg(
inputImg,
croppedAreaPixels
)
getBlob(croppedImage)
}
return (
/* need to have a parent with `position: relative`
to prevent cropper taking up whole page */
<div className='cropper'>
<Cropper
image={inputImg}
crop={crop}
zoom={zoom}
aspect={1}
onCropChange={setCrop}
onCropComplete={onCropComplete}
onZoomChange={setZoom}
/>
</div>
)
}
export default ImageCropper
3. Aşama : Görüntü dosyasını alan bir bileşen ayarlayalım.
Cropper, bir resim url'si veya base64'ü alır. Burada kullanıcının kendi resmini yüklemesine izin verdim ve ardından onu base64'e dönüştürdüm.
// ImageUpload.js
import React, { useState } from 'react'
import * as firebase from 'firebase/app'
import ImageCropper from './ImageCropper'
const ImageUpload = () => {
const [blob, setBlob] = useState(null)
const [inputImg, setInputImg] = useState('')
const getBlob = (blob) => {
// pass blob up from the ImageCropper component
setBlob(blob)
}
const onInputChange = (e) => {
// convert image file to base64 string
const file = e.target.files[0]
const reader = new FileReader()
reader.addEventListener('load', () => {
setInputImg(reader.result)
}, false)
if (file) {
reader.readAsDataURL(file)
}
}
const handleSubmitImage = (e) => {
// upload blob to firebase 'images' folder with filename 'image'
e.preventDefault()
firebase
.storage()
.ref('images')
.child('image')
.put(blob, { contentType: blob.type })
.then(() => {
// redirect user
})
}
return (
<form onSubmit={handleSubmitImage}>
<input
type='file'
accept='image/*'
onChange={onInputChange}
/>
{
inputImg && (
<ImageCropper
getBlob={getBlob}
inputImg={inputImg}
/>
)
}
<button type='submit'>Submit</button>
</form>
)
}
export default ImageUpload
4. Aşama : Görüntüyü kırpmak ve kaydetmek için işlevi ayarlayalım.
Görüntünün yalnızca 'kırpılmış' bölümünü kaydetmek için bir tuval oluşturuyoruz ve .useContext('2d')
üzerinde 2 boyutlu bir şekil oluşturuyoruz. Resmin yalnızca kırpılmış bölümünü kullanarak tuvalimizde çizeriz .drawImage()
ve ardından tuvali bir blob olarak döndürürüz.
Set canvas.width
ve canvas.height
ancak büyük Sizin (piksel) olarak kırpılan görüntüyü saklamak istiyorum. Benim için 250px'e 250px olarak tuttum.
// cropImage.js
// create the image with a src of the base64 string
const createImage = (url) =>
new Promise((resolve, reject) => {
const image = new Image()
image.addEventListener('load', () => resolve(image))
image.addEventListener('error', error => reject(error))
image.setAttribute('crossOrigin', 'anonymous')
image.src = url
})
export const getCroppedImg = async (imageSrc, crop) => {
const image = await createImage(imageSrc)
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
/* setting canvas width & height allows us to
resize from the original image resolution */
canvas.width = 250
canvas.height = 250
ctx.drawImage(
image,
crop.x,
crop.y,
crop.width,
crop.height,
0,
0,
canvas.width,
canvas.height
)
return new Promise((resolve) => {
canvas.toBlob((blob) => {
resolve(blob)
}, 'image/jpeg')
})
}
ir kullanıcı bir resim yüklediğinde, kırpıcı görünecektir. Kullanıcı daha sonra kırpılmış alanı sürükleyebilir ve içeriğine yakınlaştırabilir / uzaklaştırabilir. Gönder'e tıkladıklarında, son kırpılan resim daha sonra yüklenir (benim durumumda Firebase Storage'a) ve dosya boyutunu küçültmek için yeniden boyutlandırılır.
Biraz stil verdikten sonra ki bunu siz dilediğiniz gibi yapabilirsiniz. Benim uygulamamda şöyle görünüyor. :