Spaces:
Running
Running
File size: 4,274 Bytes
a62d4c5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
import { useCallback, useEffect, useState } from 'react'
export function dataURItoBlob(dataURI: string) {
const mime = dataURI.split(',')[0].split(':')[1].split(';')[0]
const binary = atob(dataURI.split(',')[1])
const array = []
for (let i = 0; i < binary.length; i += 1) {
array.push(binary.charCodeAt(i))
}
return new Blob([new Uint8Array(array)], { type: mime })
}
// const dataURItoBlob = (dataURI: string) => {
// const bytes =
// dataURI.split(',')[0].indexOf('base64') >= 0
// ? atob(dataURI.split(',')[1])
// : unescape(dataURI.split(',')[1])
// const mime = dataURI.split(',')[0].split(':')[1].split(';')[0]
// const max = bytes.length
// const ia = new Uint8Array(max)
// for (var i = 0; i < max; i++) ia[i] = bytes.charCodeAt(i)
// return new Blob([ia], { type: mime })
// }
export function downloadImage(uri: string, name: string) {
const link = document.createElement('a')
link.href = uri
link.download = name
// this is necessary as link.click() does not work on the latest firefox
link.dispatchEvent(
new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
})
)
setTimeout(() => {
// For Firefox it is necessary to delay revoking the ObjectURL
// window.URL.revokeObjectURL(base64)
link.remove()
}, 100)
}
export function loadImage(image: HTMLImageElement, src: string) {
return new Promise((resolve, reject) => {
const initSRC = image.src
const img = image
img.onload = resolve
img.onerror = err => {
img.src = initSRC
reject(err)
}
img.src = src
})
}
export function useImage(
file: Blob | MediaSource
): [HTMLImageElement, boolean, (width: number, height: number) => void] {
const [image, setImage] = useState(new Image())
const [isLoaded, setIsLoaded] = useState(false)
// 调整图像分辨率的函数
const adjustResolution = useCallback(
(width, height) => {
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')!
canvas.width = width
canvas.height = height
context.drawImage(image, 0, 0, width, height)
const resizedImage = new Image()
resizedImage.src = canvas.toDataURL()
setImage(resizedImage)
},
[image]
)
useEffect(() => {
const newImage = new Image()
newImage.onload = () => {
setIsLoaded(true)
}
newImage.src = URL.createObjectURL(file)
setImage(newImage)
return () => {
newImage.onload = null
}
}, [file])
return [image, isLoaded, adjustResolution]
}
// https://stackoverflow.com/questions/23945494/use-html5-to-resize-an-image-before-upload
interface ResizeImageFileResult {
file: File
resized: boolean
originalWidth?: number
originalHeight?: number
}
export function resizeImageFile(
file: File,
maxSize: number
): Promise<ResizeImageFileResult> {
const reader = new FileReader()
const image = new Image()
const canvas = document.createElement('canvas')
const resize = (): ResizeImageFileResult => {
let { width, height } = image
if (width > height) {
if (width > maxSize) {
height *= maxSize / width
width = maxSize
}
} else if (height > maxSize) {
width *= maxSize / height
height = maxSize
}
if (width === image.width && height === image.height) {
return { file, resized: false }
}
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
if (!ctx) {
throw new Error('could not get context')
}
canvas.getContext('2d')?.drawImage(image, 0, 0, width, height)
const dataUrl = canvas.toDataURL('image/jpeg')
const blob = dataURItoBlob(dataUrl)
const f = new File([blob], file.name, {
type: file.type,
})
return {
file: f,
resized: true,
originalWidth: image.width,
originalHeight: image.height,
}
}
return new Promise((resolve, reject) => {
if (!file.type.match(/image.*/)) {
reject(new Error('Not an image'))
return
}
reader.onload = (readerEvent: any) => {
image.onload = () => resolve(resize())
image.src = readerEvent.target.result
}
reader.readAsDataURL(file)
})
}
|