前兩天遇到一個小需求,需要將橫屏圖片轉為豎屏展示。整理一下相關內容。
透過 css
transform rotate 來控制展示時顯示效果
一般是在圖片稽核等場景,實現一個類似的功能。方便稽核人員檢視圖片
測試傳送門:https://stackblitz.com/edit/vue-sdrnue?file=src%2FApp.vue
transform scale 來控制展示時顯示效果
測試傳送門:https://stackblitz.com/edit/vue-pj9puy?file=src%2FApp.vue
透過 canvas 來控制展示是顯示效果
這種一般就是在生成的時候處理,落庫就是直接是豎屏圖片。
測試傳送門:https://jsrun.net/Q7JKp
rotate 來實現旋轉效果
orientation = 0 // 0
orientation = 3 // 180
orientation = 8 // 270
orientation = 6 // 90
if (orientation === 6) {
canvas4.width = canvas1.height;
canvas4.height = canvas1.width;
ctx4.rotate(Math.PI / 2);
ctx4.drawImage(canvas1, 0, -canvas1.height);
} else if (orientation === 3) {
canvas4.width = canvas1.width;
canvas4.height = canvas1.height;
ctx4.rotate(Math.PI);
ctx4.drawImage(canvas1, -canvas1.width, -canvas1.height);
} else if (orientation === 8) {
canvas4.width = canvas1.height;
canvas4.height = canvas1.width;
ctx4.rotate(-Math.PI / 2);
ctx4.drawImage(canvas1, -canvas1.width, 0);
} else {
// 如果沒有旋轉,直接繪製圖片
canvas4.width = canvas1.width;
canvas4.height = canvas1.height;
ctx4.drawImage(canvas1, 0, 0);
}
translate + rotate 來簡化旋轉
https://www.canvasapi.cn/CanvasRenderingContext2D/rotate#&syntax
瞭解CanvasRenderingContext2D.rotate()
CanvasRenderingContext2D.rotate()
給Canvas畫布新增旋轉矩陣,順時針方向,單位是弧度。
預設旋轉中心點是 Canvas 的左上角(0, 0)
座標點,如果希望改變旋轉中心點,例如以Canvas
畫布的中心旋轉,需要先使用translate()
位移旋轉中心點。
角度轉弧度計算公式是:radian = degree Math.PI / 180。例如,旋轉45°,旋轉弧度就是45 Math.PI / 180。
透過移動中心點,可以比較簡單的理解旋轉。(好像也沒簡單多少)
<canvas id="canvas5"></canvas>
<script>
var context = canvas5.getContext('2d');
canvas5.width=canvas1.height;
canvas5.height=canvas1.width;
var width = canvas5.width;
var height = canvas5.height;
// 先位移座標到中心
context.translate(width / 2, height / 2);
// 旋轉90度
context.rotate(90 * Math.PI / 180);
// 此時按照旋轉後的尺寸
// 把定位中心移動到左上角
context.translate(-1 * height / 2, -1 * width / 2);
// 繪製圖片
context.drawImage(canvas1, 0, 0, height, width);
// 座標系還原到初始
context.setTransform(1, 0, 0, 1, 0, 0);
</script>
透過 exif 來控制圖片方向
我們知道有個 exifjs 的庫可以讀取 exif 資訊,這裡我們使用另一個庫 piexifjs 來修改 exif 資訊。
測試傳送門:https://jsrun.net/MdJKp/edit
function handleFileSelect(Orientation = 1,file) {
console.log('file', file)
var zeroth = {};
var exif = {};
var gps = {};
zeroth[piexif.ImageIFD.Make] = "Make";
zeroth[piexif.ImageIFD.XResolution] = [777, 1];
zeroth[piexif.ImageIFD.YResolution] = [777, 1];
zeroth[piexif.ImageIFD.Software] = "Piexifjs";
exif[piexif.ExifIFD.DateTimeOriginal] = "2010:10:10 10:10:10";
exif[piexif.ExifIFD.LensMake] = "LensMake";
exif[piexif.ExifIFD.Sharpness] = 777;
exif[piexif.ExifIFD.LensSpecification] = [[1, 1], [1, 1], [1, 1], [1, 1]];
gps[piexif.GPSIFD.GPSVersionID] = [7, 7, 7, 7];
gps[piexif.GPSIFD.GPSDateStamp] = "1999:99:99 99:99:99";
var exifObj = {"0th":zeroth, "Exif":exif, "GPS":gps};
// 獲取當前圖片的方向值(通常在 '0th' IFD 中)
// 設定新的方向值,例如將方向設定為正常(1)
exifObj['0th'][piexif.ImageIFD.Orientation] = Orientation;//正常
// exifObj['0th'][piexif.ImageIFD.Orientation] = 2;//
var exifStr = piexif.dump(exifObj);
var reader = new FileReader();
reader.onload = function(e) {
var inserted = piexif.insert(exifStr, e.target.result);
var image = new Image();
image.src = inserted;
// image.width = 200;
var el = document.createElement('div');
el.style.border='1px solid #0cc'
el.style.padding = '20px'
el.innerHTML = Orientation
el.appendChild(image);
document.body.appendChild(el);
};
reader.readAsDataURL(file);
}
canvas1.toBlob(handleFileSelect.bind(window,1), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,2), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,3), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,4), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,5), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,6), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,7), 'image/jpeg')
canvas1.toBlob(handleFileSelect.bind(window,8), 'image/jpeg')
使用類庫實現
Cropper.js
https://fengyuanchen.github.io/cropperjs/
Cropper.js 是一個流行的用於圖片裁剪和編輯的 JavaScript 類庫。它的實現原理主要是 canvas
Cropper.js 使用 Canvas 來處理圖片的渲染和編輯。Canvas 允許動態生成和修改影像,包括裁剪、旋轉、縮放等操作
透過捕獲使用者的滑鼠或觸控事件來實現使用者與裁剪框的互動
也支援 api 式呼叫,可以方便開發者二開
Cropper.js 可以生成裁剪後的影像資料,可以作為 Blob 物件、Base64 編碼的字串或其他格式輸出。使用者可以使用這些資料進行儲存、上傳或其他後續處理
konvajs
Konva.js 是一個用於 Canvas 上圖形渲染和互動的 JavaScript 類庫。它的實現原理也是 Canvas,但是會有圖形、圖層等概念
提供了多種使用者操作的回撥,如拖拽、縮放、旋轉、點選、雙擊等。允許為圖形物件新增事件監聽器,以便在使用者與圖形物件互動時觸發自定義邏輯。
react-image-magnify
https://ethanselzer.github.io/react-image-magnify/#/lens
openseadragon
https://openseadragon.github.io/#examples-and-features
panzoom
https://timmywil.com/panzoom/demo/
SmartPhoto
https://appleple.github.io/SmartPhoto/#group=animal&photo=camel
總結
如果只是顯示效果,可以透過 transform 修改 rotate,可以很快的實現效果
exif 的 Orientation 也是一個思路,但是 exif 支援也不一定穩定
如果為了相容性,可以考慮使用 cavnas 直接將原圖修改並落庫
最後,如果是為了稽核者檢視,可以使用一些開源的庫,基本上都會比較完善的支援圖片的放大、縮小、旋轉、拖動,當然有一些也會支援圖集。
講完了,選擇適合自己的就好