Skip to content

Commit

Permalink
Merge pull request #4382 from traPtitech/feat/fix_image_resizer
Browse files Browse the repository at this point in the history
picaを使用しないようにして、iOSでの処理の分岐をやめた
  • Loading branch information
nokhnaton authored Oct 24, 2024
2 parents 44d3bbd + 9498faa commit bce3525
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 98 deletions.
46 changes: 0 additions & 46 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"highlight.js": "^11.10.0",
"idb-keyval": "^6.2.0",
"mitt": "^3.0.0",
"pica": "^9.0.1",
"skyway-js": "^4.4.5",
"text-field-edit": "^3.2.0",
"throttle-debounce": "^5.0.2",
Expand All @@ -59,7 +58,6 @@
"@types/katex": "^0.16.7",
"@types/markdown-it": "^12.2.3",
"@types/node": "^20.14.10",
"@types/pica": "^9.0.4",
"@types/punycode": "^2.1.4",
"@types/serviceworker": "^0.0.99",
"@types/throttle-debounce": "^5.0.2",
Expand Down
4 changes: 3 additions & 1 deletion src/lib/resize/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export const resetCanvas = (
$canvas.width = width
$canvas.height = height
if ($img) {
$canvas.getContext('2d')?.drawImage($img, 0, 0)
$canvas
.getContext('2d')
?.drawImage($img, 0, 0, $canvas.width, $canvas.height)
}
}

Expand Down
54 changes: 18 additions & 36 deletions src/lib/resize/index.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,21 @@
import { loadPica } from './pica'
import { deleteCanvas, loadImage, resetCanvas } from './canvas'
import type { Dimensions } from './size'
import { needResize, getThumbnailDimensions } from './size'
import { isIOS } from '/@/lib/dom/browser'
import { mimeToFileType } from '/@/lib/basic/file'
import { createMutex } from '/@/lib/basic/async'

const mutex = createMutex()

export const canResize = (mime: string) =>
['image/png', 'image/jpeg'].includes(mime)
export const isJpeg = (mime: string) => mime === 'image/jpeg'

const iOSFlag = isIOS()
// iOSではcanvasサイズの上限が決まっているため
// Canvas area exceeds the maximum limit (width * height > 16777216).
const cannotResizeWhenIOS = ({ width, height }: Readonly<Dimensions>) =>
iOSFlag && width * height > 16777216

const resize = async (
inputFile: Readonly<File>
): Promise<File | 'cannot resize' | 'error' | null> => {
// picaでは一つの画像を並列で処理するため、複数の画像を同時に処理しないようにする
await mutex.lock()

const inputUrl = URL.createObjectURL(inputFile as File)

const pica = await loadPica()
const $input = document.createElement('canvas')
const $output = document.createElement('canvas')

const finish = <T>(result: T) => {
deleteCanvas($input)
deleteCanvas($output)
URL.revokeObjectURL(inputUrl)
mutex.unlock()
return result
}

Expand All @@ -48,19 +29,16 @@ const resize = async (
return finish(null)
}

if (cannotResizeWhenIOS(inputSize)) {
return finish('cannot resize')
}

resetCanvas($input, inputSize, $img)
resetCanvas($input, getThumbnailDimensions(inputSize), $img)

const outputSize = getThumbnailDimensions(inputSize)
resetCanvas($output, outputSize)
await pica.resize($input, $output, {
filter: 'mks2013'
const output = await await new Promise<Blob | null>(resolve => {
$input.toBlob(resolve, inputFile.type)
})

const output = await pica.toBlob($output, inputFile.type)
if (output === null) {
return finish('cannot resize')
}

const outputFile = new File([output], inputFile.name, {
type: inputFile.type,
lastModified: inputFile.lastModified
Expand All @@ -81,7 +59,7 @@ const tooLargeFileMessage =
window.traQConfig.tooLargeFileMessage ??
'大きい%sの共有には別のサービスを利用してください。'

const IMAGE_MAX_SIZE_EXCEEDED_MESSAGE = `画像サイズは20MBまでです\n${tooLargeFileMessage.replace(
const IMAGE_MAX_SIZE_EXCEEDED_MESSAGE = `リサイズ後の画像サイズが20MBを超えています\n${tooLargeFileMessage.replace(
'%s',
'画像'
)}`
Expand All @@ -93,10 +71,7 @@ const FILE_MAX_SIZE_EXCEEDED_MESSAGE = `ファイルサイズは30MBまでです
export const getResizedFile = async (file: File) => {
const fileType = mimeToFileType(file.type)

if (fileType === 'image' && file.size > IMAGE_SIZE_LIMIT) {
throw new Error(IMAGE_MAX_SIZE_EXCEEDED_MESSAGE)
}
if (file.size > FILE_SIZE_LIMIT) {
if (fileType !== 'image' && file.size > FILE_SIZE_LIMIT) {
throw new Error(FILE_MAX_SIZE_EXCEEDED_MESSAGE)
}

Expand All @@ -110,11 +85,18 @@ export const getResizedFile = async (file: File) => {
}

const res = await resize(file)

if (res === 'cannot resize') {
throw new Error('画像が大きいためサムネイルは生成されません')
throw new Error('画像のリサイズに失敗しました')
}
if (res === 'error') {
throw new Error('画像の形式が不正なためサムネイルは生成されません')
}
return res ?? file
if (res === null) {
return file
}
if (res.size > IMAGE_SIZE_LIMIT) {
throw new Error(IMAGE_MAX_SIZE_EXCEEDED_MESSAGE)
}
return res
}
13 changes: 0 additions & 13 deletions src/lib/resize/pica.ts

This file was deleted.

0 comments on commit bce3525

Please sign in to comment.