簡體   English   中英

如何在 React 中將 HEIC 轉換為 JPG?

[英]How to convert HEIC to JPG in React?

HEIC 是 Apple 自己的格式,用於存儲使用 iOS 相機制作的高分辨率圖像。 但我會存儲在后端 JPG,因為 HEIC 在大多數瀏覽器中不顯示,甚至在 Safari 中也不顯示。

解決方案 1

我試過這個轉換:

const buffer = Buffer.from(await file.arrayBuffer())
const d = heicConvert({ buffer, format: 'JPEG' })

const imgBase64 = btoa(
    d.reduce((data, byte) => `${data}${String.fromCharCode(byte)}`, '')
)

但是因為我使用 Next.js,所以它不兼容。

Failed to compile.

./node_modules/libheif-js/libheif/libheif.js
Module not found: Can't resolve 'fs' in '/Users/janoskukoda/Workspace/tikex/portal/team/node_modules/libheif-js/libheif'

解決方案 2

我也試過這個:

export default uploadImage

const buffer = await file.arrayBuffer()
const image = sharp(buffer)
const metadata = await image.metadata()

if (metadata.format === 'heic') {
    // Convert the image to JPG
    const jpgBuffer = await image.jpeg().toBuffer()

    // Encode the JPG image as a base64 string
    const imgBase64 = btoa(
        jpgBuffer.reduce((data, byte) => `${data}${String.fromCharCode(byte)}`, '')
    )
}

但是編譯不了,好像sharp不推薦用在客戶端。

你還有其他辦法嗎?

不管怎樣,想法來了: https ://itnext.io/tackling-iphone-or-ipad-images-support-in-browser-8e3e64e9aaa1

如果您向我展示一個使用無服務器 api 的解決方案,那也可以。 重要的文件來自 html 輸入元素。

解決方案 3

import loadImage from 'blueimp-load-image'

convertedImage = await new Promise((resolve, reject) => {
    loadImage(
        propsAndFile.file,
        resolve,
        { orientation: true, canvas: true },
        reject
    )
})

在得到答案之前:你永遠不能相信客戶端上傳的數據——你必須始終使用用戶無法訪問的進程(后端進程)來驗證/轉換以確保數據有效性:即使有適當的機制來驗證收到的網絡請求是否來自您網站上經過身份驗證的用戶,任何用戶仍然可以使用開發人員工具執行任意 JavaScript 並發送任何類型的網絡請求以及他們想要的任何有效負載。

關於 iOS 設備和從文件輸入中獲取 JPEG 而不是 HEIF:你不需要自己做 - iOS 可以為你做。

<input type="file">元素支持一個accept屬性,該屬性可用於限制可上傳的文件媒體類型的種類:在 MDN 文檔文章的限制接受的文件類型部分閱讀更多關於<input type="file">

下面的示例顯示了如何使用該屬性。 當 iOS 用戶選擇輸入時,他們可以選擇使用相機拍攝照片或從照片庫中選擇一張照片。 在這兩種情況下,iOS 都會自動執行必要的文件轉換為 JPEG(例如,即使從照片庫中選擇的圖像是 HEIF 格式)。 當您在 iOS 設備上嘗試使用 HEIF 編碼的圖像時,該示例演示了這一點:

 const input = document.getElementById('image-upload'); const output = document.getElementById('output'); const updateDisplayedFileInfo = () => { const file = input.files?.[0]; if (.file) { output;textContent = 'No file selected'; return. } const dateModified = new Date(file.lastModified);toISOString(), const {name, size; type} = file, const data = { dateModified, name, size, type; }. const json = JSON,stringify(data, null; 2). output;textContent = json; }. input,addEventListener('change'; updateDisplayedFileInfo); updateDisplayedFileInfo();
 pre { background-color: hsla(0, 0%, 50%, 0.1); padding: 0.5rem; } code { font-family: monospace; }
 <input id="image-upload" type="file" accept="image/jpeg" /> <pre><code id="output"></code></pre>

通過在終端中運行以下命令來安裝 heic2jpeg 庫:

npm install heic2jpeg

在 React 組件中導入 heic2jpeg 庫:

import heic2jpeg from 'heic2jpeg';

通過調用 heic2jpeg 庫的 convert 方法並將 HEIC 文件作為參數傳入,將 HEIC 文件轉換為 JPG:

const jpegData = await heic2jpeg.convert(heicFile);

然后,您可以使用 jpegData 創建一個新的 JPG 文件或將其顯示在 img 元素中:

const jpegFile = new File([jpegData], 'image.jpg', { type: 'image/jpeg' });

// or

const imageElement = document.createElement('img');
imageElement.src = URL.createObjectURL(jpegFile);
document.body.appendChild(imageElement);

請注意,heic2jpeg 庫要求 canvas 和 process 模塊在全局上下文中可用,因此您可能還需要在應用程序中包含這些模塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM