前言
Samsung S25 Ultra有3D拍照與錄影的功能,繼前幾天研究完用工具拆S25的3D照片,用ffmpeg轉S25U拍的3D影片給YouTube用,和用ffmpeg轉S25U拍的3D影片給YouTube用後在想,手機上有沒有辦法處理Samsung S25U拍出來的3D照片呢?查了一下大神StereoPhoto,感覺好像只有針對apple在弄,晃了一陣子後突然發現有人做了For apple的全前端的版本。想了想後就拿著已知的資訊"web based","heic","0:g:2","0:g:3"這些東西問Copilot,然後問來問去就生成這個工具了。
為了把東西塞到我的blog內,把變數全部都壓個日期以免撞到不該撞的。順帶一提,恭喜IDOLMASTER Million Live Theater Days九周年。剛好日期都壓著今天。
##ReadMore##
紀錄
結果出國一趟,拍照拍一拍,自己用一用,覺得轉換速度太慢,回來後把原本的核心從HEIC2ANY參考神人換成了LIBHEIF-JS,然後因為使用途中發現用到5張圖片就換轉換失敗,所以又改寫了回收記憶體的部分,取消預讀快取,同時又加上了平行處理(inline worker)的部分。
實際測試,轉換30張圖,S25U 30張圖轉換,2T約16秒,8T約9秒;轉換100張圖,2T 54.5秒,8T 37.7秒。先這樣吧,比之前應該快超多了
這年頭code都可以讓AI生出來,真的很恐怖,我自己去看lib,去看console除錯,花的時間可能要十倍有,但人類還是要看程式碼的邏輯跟AI寫出來的有沒有在唬爛。
20260716(build0036): 發現Android不給讀真實檔名。加入透過libheif-js解析HEIC EXIF的時間功能當作檔名,預設為開,同時加入了讀EXIF binary寫到merge後的jpg的功能。
20260717(build0037): 參考了Apple Vision Pro的格式,調整預設輸入,然後解了android用序號當檔名改用毫秒防衝突的問題。仍有些小bug例如判斷機制,防zip的沒處理,EXIF讀取地點在手機上掛掉,寫入EXIF原始binary但手機相簿認不到點。還有一點是還沒找到iphone的3d capture photo。再說吧,好累了。改code過程中有發現,Copilot雖然初始很強大,但到某個階段會有點太花時間,就像是你跟某個熟練的人討論,但他只熟練一部份,所以很容易原地轉圈。這兩天在用的_heif_item_get_item_data與heif_image_handle_get_metadata,都是我問Gemini才問到正確的用法,Copilot一直try就是沒try到核心。(更新)分析完確認S25 Ultra系統底層會對HEIC/HEIF/JPG等位置資訊抹0,EXIF中的GPSLatitude*等都會被強制寫0,無論用photo app去選或是用files去選都會,網路上在用的accept欺騙的方式只有解決拿不到原始檔名的問題,但位置還是被複寫0掉,透過全檔分區掃描hash發現只有gps區塊被複寫。由於已經實裝了讀時間作為檔名的功能,不考慮accept欺騙免得後面還要去判斷欺騙完後流進來的檔案。同一檔案複製成.bin才能解決但不切實際。
20260721(build0038): 發現流程卡display太久,分析下去看起來是libheif-js WASM沒有包平行運算,把preview的decode image拆成inline worker,1.7s>1.3s。中間有小版發現有不預期的白畫面,inline worker中檢查是沒問題的,推測是錯誤的傳遞資源。接下來要先清理一些舊code並把寫法小改,之後要來做preview能換頁。研究過程中發現preview要再加速可以考慮實作tile decode,但考慮到現在已經超過千行了…算了。
20260721(build0039): 內部版,移除舊code。
20260721(build0040): 內部版,移除舊code,tile預覽的IIFE prototype成功運作,在不轉jpg的情況下可以把生成preivew壓到0.5秒左右。成功找到ISO標準ISO/IEC 23008-12 §9.4.3.1,HEIC中敘述'ster'的立體影像標準判定且成功判讀,後續考慮把原本指定frame的功能改到實驗區域。
20260727(build0041): 實作了tile preview,把原本一次列出很多張的preview改成翻頁式preview,應該還有一些bug例如解析度指定問題之類的,先這樣吧。目前裡面三套render流程,一套標準libheif-js循序解frame,用在convert,一套libheif-js worker平行解frame,用在preview,一套libheif-js tile+worker實作,用在preview。convert由於現在出圖已經平行化處理,考慮到raw轉jpg也要0.3秒,平行tile拚圖要再平行jpg完全最佳化難度太大,即使一般商業也不會這樣做,維持現有架構。修復一部分記憶體暴增問題,透過null掉module,windows版chrome可以大幅減少在百張圖片內的記憶體使用。修復相機在右下拍攝後存EXIF照片會被圖片APP旋轉的問題。目前已經追到平行處理卡在tile decode上,極有可能不重編譯就無解。只能先這樣。
使用方式
- 點選擇檔案,多選要處理的三星S25U 3D圖HEIC,選完確定後會先偵測第一張圖做為後面解析度與HEIC結構判斷。
- 預設讀完第一張厚會選擇HEIC內從一數的第三張當左眼(超廣角),從一數的第二張當右眼(裁切的廣角)。
- 按下preview會生成前三張的圖做為預覽。
- 按下convert會開始跑生成圖片,但不會儲存。必須等到按下下載zip才會儲存。
- 因手機版不給讀真實檔名,預設讀取EXIF中日期後以yyyymmdd_hhmmss_nnn_merged.jpg為檔名,取消勾選會以瀏覽器看到的檔名+merged為檔名。切換後需要重新按下轉換,因為blob檔名是換換時寫入的。
- 預設會讀取EXIF資訊寫入,一樣,切換後需要重新按下轉換,EXIF是轉換時寫入的。
我沒有做太多防呆動作,大部分是Copilot看到後不爽幫我加上去的。除非我自己操作錯誤感到不爽,不然應該不會修改。雖然我現在已經想加個左右交換的按鈕了...
有測試過Win11的Edge,SamsungS25U的Chrome瀏覽器可以正常操作。其他的沒空試。有空再說。
HEIC Batch Merge Tool
Load HEIC from Samsung S25 Ultra 3D capture spatial photo (.HEIC) to side-by-side LR image (.jpg)
Copyrights
Except where otherwise noted, this project is licensed under © 2026 mingray/nosql (x.com/mingray, fb.me/nosql). All rights reserved. This project uses third-party libraries: - JSZip (MIT License) Source: https://stuk.github.io/jszip/ MIT License Copyright (c) 2009-2016 Stuart Knightley, David Duponchel, Franz Buchinger, António Afonso Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - libheif-js (LGPL-3.0-or-later) Source: https://github.com/catdad-experiments/libheif-js CDN: https://cdn.jsdelivr.net/npm/libheif-js@1.19.8/ All third-party libraries remain under their respective licenses. See the respective repositories and license files for complete license texts. LGPL-3.0 License: https://www.gnu.org/licenses/lgpl-3.0.html
沒有留言:
張貼留言