關於上傳圖片你應該注意的事
set: 踩坑分享
tags: Web
category: Front-End
description: 關於上傳圖片你應該注意的事 (exif 方向)
created_at: 2022/05/26 07:00:00
前言
關於這個 exif
, 在我碰到這問題之前還完全不知道這個東西,我一直以為上傳不就很單純,就算前端要預覽也就頂多加個像是 FileReader
之類的東西去讀取然後丟進 <img>
就結束了。
但是就在某一天,在有 QA
測試的環境下發生了上傳圖片但是方向錯誤的問題。
注意事項
較新的瀏覽器都會幫忙處理這個問題,而以下是 image-orientation
這個 CSS
屬性的支援度。
看上面這張圖,所以如果你想玩玩,可以考慮去下載舊版瀏覽器。
但是有趣的是,瀏覽器就算支援這個 image-orientation
的屬性,也只是單純支援這個屬性而已,有沒有幫你處理就是另一回事了(這一點會在之後貼上幾個測試案例)。
所以最好還是得依賴第三方的套件幫忙處理會比較安全。
問題 DEMO
可以看到這張圖中未處理的圖片是橫的(但實際上拍照時是直的)
在較新的瀏覽器會自動翻正,而沒有自動修正的瀏覽器也可以透過 image-orientation
去設定,但是如果真的舊到連 image-orientation
都不支援,那可能只能依賴套件了。
image-orientation
怎麼運作的?
這個屬性去決定圖片怎麼樣顯示的(方向),而他主要有兩個屬性,分別是
none
: 不做任何修正(自己處理的意思)from-image
: 從EXIF
的資訊做翻轉,這個也是預設值(?)
為什麼我放問號(?)呢,後面會說明
什麼是 EXIF 呢?
簡單說就是記錄著一些圖片資訊(metadata
)的東西,大概長下面這樣。
ExifTool Version Number : <不給你看>
File Name : <不給你看>
Directory : <不給你看>
File Size : <不給你看>
Zone Identifier : <不給你看>
File Modification Date/Time : <不給你看>
File Access Date/Time : <不給你看>
File Creation Date/Time : <不給你看>
File Permissions : <不給你看>
File Type : <不給你看>
File Type Extension : <不給你看>
MIME Type : <不給你看>
Exif Byte Order : <不給你看>
Compression : <不給你看>
Resolution Unit : <不給你看>
Make : <不給你看>
Camera Model Name : <不給你看>
Software : <不給你看>
Orientation : <不給你看>
Modify Date : <不給你看>
Y Cb Cr Positioning : <不給你看>
F Number : <不給你看>
Maker Note Unknown Text : <不給你看>
Exposure Time : <不給你看>
Sensing Method : <不給你看>
Sub Sec Time Digitized : <不給你看>
Sub Sec Time Original : <不給你看>
Sub Sec Time : <不給你看>
Focal Length : <不給你看>
Flash : <不給你看>
Light Source : <不給你看>
ISO : <不給你看>
Metering Mode : <不給你看>
Create Date : <不給你看>
Exposure Compensation : <不給你看>
Date/Time Original : <不給你看>
White Balance : <不給你看>
Aperture Value : <不給你看>
Exposure Mode : <不給你看>
Exposure Program : <不給你看>
Shutter Speed Value : <不給你看>
Components Configuration : <不給你看>
Color Space : <不給你看>
Exif Version : <不給你看>
X Resolution : <不給你看>
Y Resolution : <不給你看>
Thumbnail Offset : <不給你看>
Thumbnail Length : <不給你看>
JFIF Version : <不給你看>
Image Width : <不給你看>
Image Height : <不給你看>
Encoding Process : <不給你看>
Bits Per Sample : <不給你看>
Color Components : <不給你看>
Y Cb Cr Sub Sampling : <不給你看>
Aperture : <不給你看>
Image Size : <不給你看>
Megapixels : <不給你看>
Shutter Speed : <不給你看>
Create Date : <不給你看>
Date/Time Original : <不給你看>
Modify Date : <不給你看>
Thumbnail Image : <不給你看>
Focal Length : <不給你看>
Light Value : <不給你看>
而方向應該就是看這一個資訊 Orientation
。
關於舊版瀏覽器的測試心得(?)
以 Firefox
為例,我總共載了幾個版本來測試XD
版本 | 自動修正 | 支援屬性 | 預設值 |
---|---|---|---|
25 | F | F | - |
26 | F | T | 0deg |
63 | F | T | none |
64 | F | T | none |
99 | T | T | from-image |
上面可以看到,在比較新版的才支援自動修正,而比較舊的瀏覽器的預設值還不是 from-image
,所以我才會在最上面說明的時候打一個問號(?)
解決方案
- 自己去抓
exif
的方向值在自己做翻轉(太累了 跳過) 是有一些方式可以抓到這個資訊,有興趣可以自己看看:
- https://stackoverflow.com/questions/7584794/accessing-jpeg-exif-rotation-data-in-javascript-on-the-client-side
- https://github.com/exif-js/exif-js (這個應該也可以,我自己沒用過)
一般來說抓出來數字如果合法,應該會是下面其中一種可能,然後再依據數字判斷如何翻回來。
1 2
██████ ██████
██ ██
████ ████
██ ██
██ ██
3 4
██ ██
██ ██
████ ████
██ ██
██████ ██████
5 6
██████████ ██
██ ██ ██ ██
██ ██████████
7 8
██ ██████████
██ ██ ██ ██
██████████ ██
上面的方法比較麻煩,所以可以採用套件完成。
功用就跟名字一樣,用他讀取圖片的話,可以設定請他幫你調整,而且這樣的話連 Firefox 25
都支援。
最基本的用法
- 使用
Callback
loadImage(
'<Blob object or image URL>',
function (image) {
},
{
orientation: true,
}
)
- 使用
Promise
loadImage(
'<Blob object or image URL>',
{
orientation: true,
}
).then(data => {
const image = data.image
})
這時候你就會拿到處理完的圖片了。