Skip to content

Instantly share code, notes, and snippets.

@kenmori
Last active March 27, 2020 22:04
Show Gist options
  • Save kenmori/fe204e0970c2d77b81ea0b857a2303b3 to your computer and use it in GitHub Desktop.
Save kenmori/fe204e0970c2d77b81ea0b857a2303b3 to your computer and use it in GitHub Desktop.
【解決】[Solution] Support for tilting 90 degrees when uploading an iPhone image file(iPhoneの画像ファイル(File)をアップロードすると横向きに(90度回転)傾く対応)

【解決】iPhoneの画像ファイル(File)をアップロードすると横向きに(90度回転)傾く対応)

Upload the iPhone image file (File) to tilt horizontally (rotate 90 degrees) ~ iPhoneの画像ファイル(File)をアップロードした際に90度傾く対応) ~

フロントエンドでEXIFという画像のメタデータ内のOrientationの値を考慮して処理しないとそうなる。

よくある記事はimageのnodeに突っ込んでプレビューに出すみたいなのは多いのだけれど、 そうではなく、File型としてセットしたい時の方法。 callback関数を渡して、そこに処理させる

This will happen if the front end does not take into account the value of Orientation in the metadata of the image called EXIF. There are a lot of common articles that go into the image node and appear in the preview, Otherwise, if you want to set it as a File type. Pass the callback function and let it process there

例えば setStateをしたい時とか For example, when you want to do setState

  • React
  • TypeScript
  • formik
  • blueimp-load-image

install

  • blueimp-load-image
  • @types/blueimp-load-image

package.json

“blueimp-load-image”: “^2.26.0",
“@types/blueimp-load-image”: “^2.23.5",

create module so that it can be used anywhere

モジュール化しちゃう

import loadImage, { MetaData, LoadImageOptions } from 'blueimp-load-image'

export const setFileWithValiedMetaInfo = (
    file: File,
    callback: (blob: Blob) => void
) => {
    loadImage.parseMetaData(file, (data: MetaData) => {
        const options: LoadImageOptions = {
            canvas: true
        }
        if (data.exif) {
            // exif(写真が持つmeta情報)
            options.orientation = (data.exif as {
                // __proto__が持っている
                get: (id: string) => number
            }).get('Orientation') // 写真のOrientationが6の場合反時計回りに90度傾いてアップロードされてしまう対応
        }
        loadImage(
            file,
            (canvas: Event | HTMLCanvasElement | HTMLImageElement) => {
                const dataUri = (canvas as HTMLCanvasElement).toDataURL(
                    'image/jpeg'
                )
                // dataUriからFileオブジェクトに変換
                const byteString = atob(dataUri.split(',')[1])
                const target = dataUri.match(/(:)([a-z]+)(;)/)
                const mimeType = target ? target[2] : 'image/jpeg'
                for (
                    var i = 0,
                        l = byteString.length,
                        content = new Uint8Array(l);
                    l > i;
                    i++
                ) {
                    content[i] = byteString.charCodeAt(i)
                }

                const blob = new Blob([content], {
                    type: mimeType
                })
                callback(blob)
            },
            options
        )
    })
}

how to use

使い方

const setFileValue = React.useCallback((blob: Blob) => {
    // setFieldValue(‘avatar’, blob) // formikでセットしていた関数をそのまま渡して処理してもらう
    imageUpload.setFileWithValiedMetaInfo(file, setFileValue) // pass set function as callback
}, [])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment