3D塊攝像頭
BlockCam是用於iOS和iPados的相機程序,可通過Avoundation拍攝圖像,然後將這些圖像轉換為簡單的3D場景。場景可以由用戶旋轉和縮放,並保存為平面圖像。
BlockCam由Stuart Rankin撰寫。
blockCAM的版本控制在Versioning.swift文件中維護,並自動更新每個構建作為前構建腳本步驟。更新包括構建ID,構建數字,時間和日期,但是當前必須手動更新版本號。下面的當前構建字符串也通過相同的機制維護。
版本管理程序當前未更新塊cam項目文件的版本號。
最新構建: 0.9 Alpha,Build 3287,構建日期:2021年7月13日,16:06
有關版本和構建方式更新的信息,請參見GITHUB上的版本Updater存儲庫。
BlockCAM旨在盡可能包含用戶提供的信息。每當使用用戶可識別的信息時,BlockCam都會明確要求。通過設計,塊狀攝影機不會默認收集任何可識別的信息;用戶必須採取主動步驟以允許收集此類信息。
| 可識別的信息 | 使用 | 貯存 |
|---|---|---|
| 使用者名稱 | 用戶的名稱(用戶輸入)將存儲在處理後的圖像元數據中。 | 存儲在UserDefaults中。 |
| 用戶版權 | 用戶的版權字符串(由用戶輸入)存儲在處理後的圖像元數據中。 | 存儲在UserDefaults中。 |
當用戶實例化塊狀攝像機時,它將在實時視圖模式下打開(在主屏幕上顯示相機的視圖)。用戶可以選擇選擇三種模式之一:
BlockCAM已在以下平台上進行了測試:
UIBezierPath添加更多形狀。BlockCam有四個表演問題:
autoreleasepool塊中的循環中,已經解決了大多數問題。如果事實證明這是不足的,則存在緩解計劃:將所有刮擦圖像保存到本地存儲中,然後單獨閱讀它們,然後一次處理它們。這會減慢速度,但會降低記憶壓力。BlockCAM通過Coreimage Filter CIPixellate將所拍攝的每個圖像轉換為像素圖像。像素化後,處理算法然後計算確定高度 - 高度確定節點的大小或節點的擠出。然後,將來自像素圖像的每個像素轉換為3D形狀(由用戶設置),然後在3D視圖中添加到當前場景中。
所有處理操作都使用相同的代碼,但根據有效的用戶模式,可能以不同的方式(或多次)調用。
獲取圖像用於處理。只要它是標準的iOS/iPados-prable圖像,圖像的來源就不重要。最常見的圖像來源很可能是現場視圖攝像頭。其他來源是相冊和視頻幀。
以下圖像是處理的來源。 (這是我在初冬拍攝我們花園的圖像。)

鑑於轉換圖像的性能費用,用戶可以選擇通過將源圖像調整到較小尺寸來減少完成的工作量。如果處理視頻,則可能在沒有用戶干預的情況下發生這種情況。 (處理視頻往往需要大量的內存,因此即使每張圖像節省了幾個百分點也會有助於使系統對系統的壓力減輕。)某些圖像也旋轉到270°(如果願意,則為-90°),並且需要正確旋轉。這也是在圖像調節步驟中完成的。
然後通過核心圖像濾波器功能將處理的圖像像素化。具體而言,最常見的過濾器塊用途是CIPixellate (儘管其他像素過濾器的使用取決於最終形狀)。每個像素化區域的大小取決於用戶設置。尺寸越小,對整體性能的影響越大,儘管CIPixellate (和濾鏡)仍然非常快。較小的像素化區域提高性能的原因是因為以後需要更多的3D節點。
下圖顯示了原始圖像的像素化。請注意,每個像素的區域都是純色,這意味著塊車不必讀取整個區域即可獲得顏色 - 只有一個像素。

然後解析像素的圖像。這需要獲取每個像素化區域的顏色。這比預期的步驟要慢。從圖像中獲取單獨的像素數據需要大量圖像數據操作,以便將圖像準備好進行查詢。在此步驟結束時,不再使用圖像。 2D顏色數據將傳遞給下一步。
在此步驟中,將像素的圖像數據保存到本地文件存儲中。這是為了簡化用戶後來要求的次要視覺更改。
最終節點形狀是用戶設置。 BlockCAM允許用戶從多種形狀之一中進行選擇 - 內置形狀往往比非構建形狀更快(例如,球體比五角星更快)。使用指定的幾何形狀從圖像解析步驟中為每種顏色生成一個3D節點。為了炫耀最終場景的3D度,節點在某種程度上被誇大了。例如,如果立方體是用戶選擇的形狀,則長度將被誇大。誇張由顏色確定 - 顏色用於陰影節點的彌散表面以及確定高度。誇張由用戶選擇的決定因素確定:
創建節點後,將其添加到主節點。創建所有節點並放入主節點後,主節點本身就會放入3D場景中。
儘管這似乎是一個微不足道的一步,但轉換視頻時非常棘手。如果轉換圖像,則所有發生的就是更新3D場景並最終顯示給用戶(通常在0.5至2.0秒內)。對於視頻,至關重要的是,正確的顯示時間表:要轉換視頻,每個幀都通過這些步驟運行,然後對3D場景進行快照。如果在顯示場景之前拍攝快照,則結果將是純黑圖像,這不是用戶想要看到的。因此,BlockCAM必須參與SCNSceneRendererDelegate集合集,以了解用戶何時可以看到場景。
以下圖像是圖像的最終處理版本。這是SCNView上的snapshot()調用的輸出。該樣本使用擠壓塊,並在默認攝像頭方向上查看。

顯示圖像後,用戶可以選擇按原樣保存或編輯某些視覺方面,或者旋轉或放大或放大,然後保存(也許是)。對於視頻,一旦捕獲了3D場景的快照,場景就被處置了。
根據.SaveOriginalImageAction的值,將保存原始圖像。當用戶保存處理的圖像時,元數據將與處理的圖像一起保存。元數據由程序的名稱和版本以及創建圖像時有效的參數組成。
保存處理的文件是一個多步驟過程:
.jpg文件保存在/Scratch目錄中。.jpg文件)重新保存。PHAssetCreationRequest - 這是需要的,因為更常見的方法將圖像移至Photo loply Strips exif數據)。/Scratch目錄中刪除。BlockCam將元數據保存在處理的文件中。
| 團體 | 標籤 | 存儲的值 |
|---|---|---|
| tiff | 藝術家 | 如果用戶啟用了用戶的名稱。 |
| tiff | 版權 | 如果用戶啟用了用戶的版權字符串。 |
| tiff | 軟體 | BlockCam的名稱,版本和構建數字。 |
| exif | 用戶 | 用於生成處理的圖像的參數列表。 |
另請參見隱私討論。
圖像處理的簡化流程圖如下所示。

由於預處理和像素化圖像所需的時間,每次處理新圖像時,像素化數據(由顏色數組組成)保存在設備的文件系統中。如果用戶更改參數(例如3D形狀),則已經完成預處理,並且重複使用像素數據。這可能會節省大量時間。
如果用戶更改影響預處理的參數,則從一開始就重新處理圖像。 (例如,更改塊大小將導致執行完整的後處理週期。)
視頻處理的簡化流程圖如下所示。立方體回到圖像流。

當前,綠色框(“處理幀”)無法按預期/所需的功能,因此在當前寫作時,不支持視頻創建。
BlockCAM在運行時記錄消息和狀態到調試控制台(如果存在,並且在絕大多數實例中,則不會存在)和本地的SQLite數據庫。如果需要,這允許在驗屍後進行調試。
鑑於蘋果公司對數據租賃的政策(更不用說歐盟的政策),對於任何已發布的塊cam,它將完全刪除(通過編譯時標誌)(通過編譯時標誌)。
所有用戶設置(以及一些流程設置)均通過Settings類存儲。該類封裝了該程序其餘部分看不見的存儲機制。當前,存儲機制是UserDefaults 。如果設置變得更加複雜,則將其遷移到數據庫非常簡單。
要訪問設置,呼叫者必須使用Settings類提供的方法。這有助於確保數據類型的完整性。
Settings類還提供更改的設置級別通知(這是首先創建類的主要原因)。
BlockCAM設置如下所示。
| 象徵 | 類型 | 預設 | 用法 |
|---|---|---|---|
| .Initialized | 細繩 | “初始化” | 確定設置是否已初始化的標誌。當BlockCAM首次運行時,如果.Initialized為NIL或空,則假定它是第一次運行BlockCam,因此請寫入所有設置的默認值。 |
| .blocksize | 整數 | 48 | 圖像處理的塊大小。這是每個像素化區域的平方尺寸。 |
| .ShapeType | 細繩 | “塊” | 每個像素區域的3D對象的相同。從枚舉中鑄造。 |
| .InvertHeight | 布爾 | 錯誤的 | 反轉高度/尺寸確定標誌。 |
| .HeightSource | 細繩 | “亮度” | 用於確定高度/尺寸的顏色通道。從枚舉中鑄造。 |
| .imagesizeconstraints | 細繩 | “中等的” | 出於性能原因,確定圖像大小的減少量。從枚舉中鑄造。在運行時解釋實際值。 |
| .VerticalExaggeration | 細繩 | “中等的” | 擠出或擴大3D形狀時要執行的垂直誇張量。從枚舉中鑄造。 |
| .InputQuality | 整數 | 2 | 表示輸入質量的值。範圍從0到3,3是最高質量(最慢的過程)。 |
| .CurrentCamera | 細繩 | “後退” | 最後一個相機的位置。前後。從枚舉中鑄造。 |
| .lightColor | 細繩 | “白色的” | 光的顏色名稱。從枚舉中鑄造。以後可以將其轉換為顏色庫類型。 |
| .lighttype | 細繩 | “ Omni” | 用於照亮場景的光的名稱。從枚舉中鑄造。 |
| 。燈強度 | 細繩 | “普通的” | 光的強度用於照亮場景。在運行時確定的實際值。從枚舉中鑄造。 |
| .fieldofview | 細繩 | “普通的” | 相機的視野。實際值在運行時確定。從枚舉中鑄造。 |
| 。示波組織圖 | 布爾 | 錯誤的 | 顯示直方圖顯示。目前尚未實施。 |
| .HistogramBucketCount | 整數 | 256 | 直方圖顯示中的顏色數量。目前尚未實施。 |
| .InitialView | 細繩 | “ Liveview” | 用戶看到的最後一個視圖(例如實時視圖,專輯等)。 |
| .FullyExtrudeLetters | 布爾 | 真的 | 確定字母是完全擠出還是僅部分擠出。 |
| 。理齒 | 細繩 | “光滑的” | 確定在字母中創建曲線的順利。高質量曲線的性能成本很高。在運行時確定的實際值。從枚舉中鑄造。 |
| .letterfont | 細繩 | “ futura” | 字體(和可選的重量)用於渲染擠出字母。如果系統上不存在字體,則塊將輸入未定義的狀態。 |
| .RandomCharacterSource | 細繩 | “拉丁” | 指定字符的字符範圍為擠出字符時隨機字母的來源。可以通過用逗號將每個範圍與其他範圍分開來指定多個範圍。 |
| .VideOfps | 整數 | 1 | 目前未使用。 |
| .VideoDimensions | 細繩 | “最小” | 生成視頻時確定最終視頻尺寸。在運行時確定的實際值。從枚舉中鑄造。 |
| .VideoBlockSize | 整數 | 48 | 視頻處理的塊大小。這是每個像素化區域的平方尺寸。 |
| .usemetal | 布爾 | 真的 | 告訴BlockCam使用金屬而不是OpenGL的標誌。 |
| .antialiasingmode | 整數 | 0 | 確定抗質量模式。 |
| .InitialBestFit | 布爾 | 錯誤的 | 如果是真的,則BlockCam將嘗試盡可能緊密地將所有節點放入視圖中。 |
| .saveoriginalimageaction | 細繩 | “總是” | 確定如何以及何時保存原始圖像。從枚舉中鑄造。 |
| .NextSequentialInteger | 整數 | 0 | 用於文件名稱。 |
| .LoopSequentialIntegerAfter | 整數 | 9999 | 確定使用順序整數時何時循環到啟動。 |
| .StartSequentialIntegerAt | 整數 | 1 | 順序整數的起始值。 |
| .IncreaseStarApexesWithProminence | 布爾 | 錯誤的 | 如果是正確的話,隨著顏色高度的突出,恆星形狀的頂點數量會增加。 |
| .starapexcount | 整數 | 5 | 恆星的頂點數。如果.IncreaseStarApexesWithProminence是正確的,則這是頂點的起始數。 |
| .HaltWhenCriticalThermal | 布爾 | 真的 | 如果是正確的話,當BlockCam收到關鍵的熱警報時,將其停止(通過fatalError呼叫)。這可能違反了蘋果準則,並可能被刪除。 |
| .haltonlowpower | 布爾 | 真的 | 如果是真的,則當塊收到低功率警報時,塊將停止(通過fatalError呼叫)。這可能違反了蘋果準則,並可能被刪除。 |
| .bestfitoffset | 雙倍的 | 2.0 | 當.InitialBestFit為真時,可以用來備份相機的價值,以給圖像提供更多的負空間。 |
| .lightingModel | 細繩 | “ phong” | 表面材料照明模型。從枚舉中鑄造。 |
| .cappedLineBalllocation | 細繩 | “頂部” | 球的位置(“蓋”)用於上限線形狀的節點。從枚舉中鑄造。 |
| .loggingEnabled | 布爾 | 錯誤的 | 啟用記錄標誌。 |
| .fontsize | 整數 | 36 | 字母的字體大小。 |
| .enableuisounds | 布爾 | 真的 | 標記播放UI聲音(例如按下按鈕時)。如果此值是false ,則所有其他聲音標誌將被忽略。 |
| .EnableShutterSound | 布爾 | 錯誤的 | 按下相機按鈕時,標誌以播放快門聲音。在某些地理位置中,這總是發生,設置此值將無效。 |
| .EnableImageProcessingSound | 布爾 | 真的 | 標誌在圖像處理的開始和結束時播放聲音。由於圖像處理時間很耗時,因此可以幫助用戶了解何時完成圖像。 |
| .EnableVideoRecordingSound | 布爾 | 真的 | 當用戶啟動並停止錄製視頻時,標誌以播放聲音。 |
| .enablebuttonpresssounds | 布爾 | 真的 | 當用戶按按鈕時,標誌以播放聲音。 |
| .enableOptionsElectSounds | 布爾 | 真的 | 當用戶在屏幕設置顯示中選擇選項時,標誌以播放聲音。 |
| .EnableCrashSounds | 布爾 | 錯誤的 | 顯示碰撞對話框時播放聲音的標誌。僅在以#debug模式進行編譯時啟用。 |
| .meshdotsize | 細繩 | “中等的” | 網格中心點的大小。如果不使用.None將不會顯示中心點。從枚舉中鑄造。 |
| 。網林 | 細繩 | “中等的” | 網狀線的厚度。從枚舉中鑄造。 |
| .RadiatingLineThickness | 細繩 | “中等的” | 輻射線形狀的厚度。從枚舉中鑄造。 |
| .radiatinglinecount | 整數 | 8 | 輻射線形狀的輻射線數。 4用於指向基本方向的線,在基本方向和介於兩者之間進行8 ,在z平面中另外16條線。 |
| .blockchamfersize | 細繩 | “沒有任何” | 倒角半徑/邊緣平滑度,用於塊狀。從枚舉中鑄造。 |
| 。末期詞 | 整數 | 1024 | 圖像的最大維度。如果要進行處理的圖像更大,則將調整大小,以使最長的維度是該值。 |
| .adduserDatatoExif | 布爾 | 錯誤的 | 標誌以將用戶創建的信息添加到處理後的圖像的Exif塊中。如果以#debug模式編譯,則此值默認為true。 |
| .使用者名稱 | 細繩 | “” | (默認值為空白。)添加到處理後圖像的Exif塊中添加的用戶提供的名稱。僅當.AddUserDataToExif為真時,才會發生這種情況。如果以#debug模式編譯,則此值默認為“ Stuart Rankin”。 |
| .UserCopyright | 細繩 | “” | (默認值為空白。)用戶提供的版權字符串被添加到處理後的圖像的Exif塊中。僅當.AddUserDataToExif為真時,才會發生這種情況。如果以#debug模式進行編譯,則此值默認為“屬性3.0 notported(cc by 3.0)”。 |
| .ConeIsInverted | 布爾 | 真的 | 確定錐形是否根據z深度倒置。 |
| .Conetoptions | 細繩 | .TopIsZero .rawValue | 確定錐體頂部半徑的選項。 |
| .conbaseOptions | 細繩 | .BaseIsSide .RawValue | 確定錐體基本半徑的選項。 |
| .showsplashscreen | 布爾 | 真的 | 標記確定在啟動時是否顯示飛濺屏幕的標誌。 |
| .hueshapelist | 細繩 | “” | 色調變體形狀類型的形狀列表。 |
| .saturationshapelist | 細繩 | “” | 飽和變體形狀類型的形狀列表。 |
| .BrightnessShapeList | 細繩 | “” | 亮度變體形狀類型的形狀列表。 |
BlockCam使用3D處理,該處理可行,可行設備的圖形芯片。如果用戶指定最高質量的設置,則可能發生某些極端情況。為了幫助保護設備免受損壞,可以在發生這種情況時可以中止塊狀攝像機的執行。
| 事件 | 行動 | 控制設置 |
|---|---|---|
| 熱的 | 如果熱事件達到臨界階段(從字面上。在通知中.critical ),則如果設置為true ,則將產生致命的誤差,以減少塊cam產生的任何熱應力。 | .HaltWhenTooHot |
| 電池 | 如果電池進入低功率狀態,如果設置為true ,則將產生致命的錯誤,以幫助保留電池的壽命,然後再充電。 | .HaltOnLowPower |
BlockCam支持以下視覺效果:
目前支持(或計劃支持)以下形狀以進行擠壓效應:
| 形狀 | 本國的 | 筆記 |
|---|---|---|
| 塊 | 是的 - SCNBox | 天然盒沿Z軸延長。 |
| 三角形 | 不 | 自定義等邊三角形。 |
| 五角星 | 不 | 定制等法五角形形狀。 |
| 六角形 | 不 | 定制等邊形狀形狀。 |
| 八生 | 不 | 定制等邊八角形狀。 |
| 金字塔 | 是的 - SCNPyramid | 本地金字塔形狀。 |
| 環形 | 是的 - SCNTorus | 本地圓環形狀。 |
| 氣缸 | 是的 - SCNCylinder | 天然圓柱形狀 - 使圓形高架圓形。 |
| 球 | 是的 - SCNSphere | 本地球體形狀。 |
| 膠囊 | 是的 - SCNCapsule | 本地膠囊形狀。聽起來不那麼有趣。 |
| 四面體 | 不 | 自定義等邊四面體固體。 |
| 星星 | 不 | 自定義星形形狀(具有徑向相等的頂點)。可以改變頂點的數量。 |
| 組合Forrgb | 是的 - 組合 | 組合球,圓環和膠囊。 |
| 聯合FORHSB | 是的 - 組合 | 組合球,圓環和膠囊。 |
| 網眼 | 不 | 目前尚未實施。 |
| 信件 | 是的 - SCNText | 本地擠出文字。往往會非常緩慢,尤其是對於非拉丁語字母。 |
| 線 | 是的 - SCNCapsule | 非常薄的膠囊形狀。 |
| 上限線 | 是的 - 組合 | 非常薄的膠囊形狀,並根據用戶設置放置在線的頂部,中或底部的球體。 |
| 輻射線 | 是的 - 組合 | 多條線從中心點輻射。用戶可以指定多少行。這是性能較重的形狀。 |
| huevarying | 變體 | 給定點的形狀由像素化區域的色調確定,因此實際的最終形狀將變化。 |
| 飽和度 | 變體 | 給定點的形狀取決於像素化區域的飽和度,因此實際的最終形狀將變化。 |
| 亮度範圍 | 變體 | 給定點的形狀取決於像素化區域的亮度,因此實際的最終形狀會有所不同。 |
代表性像素區域的每個形狀都被擠出或擴大。擠出深度或擴大尺寸的確定取決於像素區域的顏色。
| 顏色通道 | 用法 |
|---|---|
| 色調 | 顏色的色調決定了3D對象的深度/大小。請注意,色相值是周期性的(0.0基本上與1.0相同),因此在突出顯示綠色時,紅色像素往往會被屈服。 |
| 飽和 | 顏色飽和值確定深度/大小。更亮的顏色會更大。 |
| 亮度 | 顏色的亮度決定了深度/大小。這是默認值以及大多數人期望該程序的工作方式。 |
| 紅色的 | 紅色通道用於確定深度/大小。 |
| 綠色的 | 綠色通道用於確定深度/大小。 |
| 藍色的 | 藍色通道用於確定深度/大小。 |
| 青色 | 合成青色通道(來自CMYK)用於確定深度/尺寸。 |
| 品紅 | 合成洋紅色通道(來自CMYK)用於確定深度/大小。 |
| 黃色的 | 合成黃色通道(來自CMYK)用於確定深度/尺寸。 |
| 黑色的 | 合成黑通道(來自CMYK)用於確定深度/大小。 |
| YUV:Y | YUV轉換的合成Y通道。 |
| YUV:U | 來自YUV轉換的合成U通道。 |
| YUV:v | YUV轉換的合成V通道。 |
BlockCam支持倒置的標誌。這意味著,如果用戶設置倒置,則深度/大小本身就是一個互惠,使黑暗的區域突出和柔和的區域柔和或隱藏。
阻滯劑支持更改光的顏色以及光的類型。目前,顏色僅限於一小部分預定義的顏色。燈的類型並行場景的標準,非參數化的燈(例如.omni和.spot )。
目前,用戶無法調整燈的位置。
BlockCAM利用SCNView的allowsCameraControl標誌,使用戶通過手勢放大,Shink或旋轉(以三個軸為旋轉)。
最初渲染時,結果似乎遠離視圖。 BlockCAM具有可將圖像適合視圖的用戶定義標誌。對於擴大和收縮,此功能傾向於混淆allowsCameraControl 。
本節將討論各種實施級別的詳細信息。
BlockCam用Xcode 11.3寫在Swift 5中。
考慮到處理圖像所需的時間很長,所有圖像處理均在背景線程上完成。這需要所有通信以通過適當的線程調用來通過UI更新用戶。
TBD
BlockCam是版權所有©2019,2020撰寫的Stuart Rankin
日本語版«Google翻訳で翻訳»
3dブロックカメラ
blockcamはIOSおよびiPados 用のカメラプログラムで、 iPados 用のカメラプログラムで、 ios を介して畫像を取得し、それらの畫像を単純な ios を介して畫像を取得し、それらの畫像を単純な ios を介して畫像を取得し、それらの畫像を単純な 3d シーンに変換します。シーンは、ユーザーによって回転および拡大縮小され、フラットイメージとして保存されます。
BlockcamはStuart Rankinによって作成されました。
blockcamのバージョン管理はVersioning.swiftファイルで管理され、ビルド前のスクリプトステップとしてビルドごとに自動的に更新されます。 ファイルで管理され、ビルド前のスクリプトステップとしてビルドごとに自動的に更新されます。更新にはビルド、ビルド番號、時刻、日付が含まれますが、現在、バージョン番號は手動で更新する必要があります。 、ビルド番號、時刻、日付が含まれますが、現在、バージョン番號は手動で更新する必要があります。 、ビルド番號、時刻、日付が含まれますが、現在、バージョン番號は手動で更新する必要があります。
現在、バージョン管理プログラムは blockcamプロジェクトファイルのバージョン番號を更新しません。
最新のビルド:バージョン情報については、英語のセクションを參照してください。
バージョンとビルドの更新方法については、 githubの[versionupdater](https://github.com/sjrankin/versionupdater)リポジトリを參照してください。
blockcam は、可能な限りユーザーが提供する情報を含むように設計されています。 blockcamはそれを明示的に要求します。はそれを明示的に要求します。はそれを明示的に要求します。はそれを明示的に要求します。はデフォルトでユーザーを特定できる情報を收集しません。はデフォルトでユーザーを特定できる情報を收集しません。はデフォルトでユーザーを特定できる情報を收集しません。はデフォルトでユーザーを特定できる情報を收集しません。
| 識別情報 | 使用 | 保管 |
|---|---|---|
| ユーザー名 | ((()。 | 「用戶默認fefaults」に保存されます。 |
| ユーザー著作権 | ((()。 | 「用戶默認fefaults」に保存されます。 |
ユーザーが(blockcam)(をインスタンス化すると、ライブビューモードで開きます(メイン畫面にカメラのビューを表示)。ユーザーには、次の 3つのモードのいずれかを選択するオプションがあります。
阻滯は、次のプラットフォームでテストされています。
1.主な問題はパフォーマンスです。 古い携帯電話の大きなサイズの画像で使用すると、パフォーマンスが大幅に低下します。 ただし、セルフィーカメラは実際には非常に高速です。 BlockCamには、パフォーマンスの問題を軽減するのに役立つ特定の軽減策(ユーザー設定など)があります。 2. *漢字は非常に遅いです。*漢字を使用して押し出し画像を作成するには、古いiPhoneの場合、6分程度かかります。 3.以下でのみテスト済み:iPhone 6S +、iPhone 8、iPad Mini4。iPadPro 9.7。 4. MacCatalystは、MacカメラのAVFoundationの使用をサポートしていないため、非常に困難です。 MacCatalystバージョンでの作業は、その妨害のため現在のところ停止しています。 5.ヒストグラムはまだ実装されていません。 6.非組み込みの幾何学的図形は、組み込みの図形よりも大幅に遅いように見えます。 7. iPadOSおよびiOS 13には、混乱するデバッグセッションにつながるいくつかの追加のデバッグステートメントが残っているようです。具体的には、「BackgroundTaskを終了できません」メッセージです。
UIBezierPathを使用してさらにシェイプを追加します。 2.処理済みのライブビュー(現在の写真モードと同様)のみを表示する処理済みライブビューモードを追加します。 これはおそらく非常に電力を消費し、遅くなり、最新のハードウェアでのみ確実に動作する可能性があります。 3.ビデオを共有する-現在、画像のみを共有できます。 4.ピクセル化されたデータの使用を完全に実装します。 ほとんどのコードが配置されています。 この機能は、処理された画像データをピクセル化レベル(たとえば、各ピクセル領域の色)でユーザーのファイルシステム空間にファイルとして保存します。 利点は、形状や押し出しの深さなどの特定の設定をユーザーが変更したときに処理を高速化することです。 BlockCamには、パフォーマンスに関する4つの懸念事項があります。
BlockCamは、取り込まれた各画像をCoreImageフィルターCIPixellateを介してピクセル化された画像に変換します。 ピクセル化の後、処理アルゴリズムは高さの決定を計算します-高さはノードのサイズまたはノードの押し出しを決定します。 次に、ピクセル化された画像の各ピクセルが3D形状(ユーザーが設定)に変換され、3Dビューの現在のシーンに追加されます。
すべての処理操作は同じコードを使用しますが、有効なユーザー向けモードに応じて異なる方法(または複数回)で呼び出すことができます。
処理のために画像が取得されます。画像のソースは、iOS / iPadOSで読み取り可能な標準の画像である限り重要ではありません。画像の最も一般的なソースは、おそらくライブビューカメラです。他のソースは、フォトアルバムとビデオフレームです。
次の画像は、処理のソースです。 (これは私が初冬に庭で撮った画像です。)

画像を変換するためのパフォーマンスの犠牲を考えると、ユーザーはソース画像をより小さなサイズにサイズ変更することにより、実行される作業量を削減するオプションがあります。これは、ビデオが処理される場合、ユーザーの介入なしに発生することもあります。 (ビデオの処理は多くのメモリを消費する傾向があるため、画像ごとに数パーセントを保存してもシステムのストレスを軽減できます。)一部の画像は270°(または必要に応じて-90°)に回転され、正しく回転します。これは、画像調整ステップでも行われます。
処理された画像は、Core Imageフィルター関数を介してピクセル化されます。具体的には、BlockCamが使用する最も一般的なフィルターは「CIPixellate」です(ただし、最終的な形状に応じて他のピクセル化フィルターが使用されます)。各ピクセル化領域のサイズは、ユーザー設定によって異なります。サイズが小さいほど、全体的なパフォーマンスへの影響は大きくなりますが、「CIPixellate」(およびフィルターと同様)は依然として非常に高速です。ピクセル化された領域が小さくなるとパフォーマンスが向上する理由は、後でより多くの3Dノードが必要になるためです。
次の画像は、元の画像のピクセル化を示しています。各ピクセル化された領域は単色であることに注意してください。つまり、BlockCamは領域全体を読み取って色を取得する必要はなく、1ピクセルだけです。

次に、ピクセル化された画像が解析されます。これには、ピクセル化された各領域の色を取得する必要があります。これは予想よりも遅いステップです。画像から個々のピクセルデータを取得するには、画像を照会できるようにするためだけに大量の画像データ操作が必要です。この手順の最後に、画像は使用されなくなります。カラーデータの2D配列が次のステップに渡されます。
このステップでは、ピクセル化された画像データがローカルファイルストレージに保存されます。 これは、後でユーザーが要求する小さな視覚的な変更を簡素化するためです。
最終的なノード形状はユーザー設定です。 BlockCamを使用すると、ユーザーは多くの形状のいずれかを選択できます。組み込みの形状は、非組み込みの形状よりも速く動作する傾向があります(たとえば、球体は五角形よりも高速です)。指定したジオメトリを使用して、イメージ解析ステップから各色の3Dノードが生成されます。最終シーンの3D性を誇示するために、ノードはある次元で誇張されています。たとえば、キューブがユーザーが選択した形状である場合、長さは誇張されます。誇張は色によって決定されます-色は、ノードの拡散表面を陰影付けするために、また高さを決定するために使用されます。誇張は、ユーザーが選択可能な決定要因によって決定されます。
ノードが作成されると、そのノードはマスターノードに追加されます。すべてのノードが作成されてマスターノードに配置されると、マスターノード自体が3Dシーンに配置されます。
-マスターノードは、後のアニメーションを管理しやすくするために使用されます。
これは簡単な手順のように思えるかもしれませんが、ビデオを変換するときは非常に注意が必要です。画像を変換すると、3Dシーンが更新され、最終的にユーザーに表示されます(通常は0.5〜2.0秒以内)。ビデオの場合、ディスプレイのタイミングを正確にすることが重要です。ビデオを変換するには、各フレームをこれらの手順で実行し、3Dシーンのスナップショットを取得します。シーンが表示される前にスナップショットが撮られた場合、結果は純粋な黒のイメージになりますが、これはユーザーが見たいものではありません。したがって、BlockCamはSCNSceneRendererDelegate関数セットに参加して、シーンが実際にユーザーに表示されるタイミングを知る必要があります。
次の画像は、画像の最終的な処理済みバージョンです。これは、SCNViewでのsnapshot()呼び出しの出力です。サンプルは押し出しブロックを使用し、デフォルトのカメラの向きで表示されています。

画像が表示されると、ユーザーはそれをそのまま保存するか、いくつかの視覚的側面を編集するか、回転またはズームインまたはズームアウトしてから保存する(おそらくもう一度)オプションがあります。ビデオの場合、3Dシーンのスナップショットがキャプチャされると、シーンは破棄されます。
.SaveOriginalImageActionの値に応じて、元の画像が保存されます。 ユーザーが処理された画像を保存すると、メタデータは処理された画像とともに保存されます。 メタデータは、プログラムの名前とバージョン、およびイメージの作成時に有効なパラメーターで構成されます。
処理されたファイルの保存は、複数ステップのプロセスです。
.jpgファイルとして/Scratchディレクトリに保存されます。.jpgファイルとして)。PHAssetCreationRequestを使用します-写真ロールに画像を移動するより一般的な方法はExifデータを削除するためです)。/Scratchディレクトリから削除されます。BlockCamは、処理されたファイルにメタデータを保存します。
| グループ | タグ | 保存された値 |
|---|---|---|
| TIFF | アーティスト | ユーザーが有効にした場合、ユーザーの名前。 |
| TIFF | 著作権 | ユーザーが有効にした場合、ユーザーの著作権文字列。 |
| TIFF | ソフトウェア | BlockCamの名前、バージョン、ビルド番号。 |
| exif | UserComment | 処理済み画像の生成に使用されるパラメーターのリスト。 |
画像の前処理とピクセル化には時間がかかるため、新しい画像が処理されるたびに、ピクセル化データ(色の配列で構成される)がデバイスのファイルシステムに保存されます。 その後、ユーザーがパラメーター(3D形状など)を変更した場合、前処理は既に完了しており、ピクセル化データは再利用されます。 これにより、大幅に時間を節約できる可能性があります。
ユーザーが前処理に影響するパラメーターを変更すると、画像は最初から再処理されます。 (たとえば、ブロックサイズを変更すると、完全な再処理サイクルが実行されます。)
BlockCamは、実行時のメッセージとステータスをデバッグコンソール(存在する場合、大部分のインスタンスでは存在しない)とローカルSQLiteデータベースに記録します。 これにより 必要が生じた場合の事後デバッグ。
Appleのデータ保持に関するポリシー(EUのポリシーは言うまでもありません)を考えると、BlockCamのすべてのリリースバージョンのログは(コンパイル時フラグを介して)削除される可能性が高いです。
すべてのユーザー設定(およびいくつかのプロセス設定)は、 Settingsクラスを介して保存されます。 このクラスは、プログラムの残りの部分からは見えないストレージメカニズムをカプセル化します。 現在、ストレージメカニズムはUserDefaultsです。 設定がより複雑になった場合、これをデータベースに移行するのは簡単です。
設定にアクセスするには、呼び出し側はSettingsクラスの提供されたメソッドを使用する必要があります。 これにより、データ型の整合性を確保できます。
Settingsクラスは設定レベルの変更通知も提供します(これが最初にクラスを作成する主な理由でした)。
BlockCamの設定を以下に示します。
| 記号 | タイプ | デフォルト | 使用法 |
|---|---|---|---|
| .Initialized | 細繩 | "Initialized" | 設定が初期化されたかどうかを決定するフラグ。 BlockCamが最初に実行されるときに、 .Initializedがnilまたは空の場合、BlockCamが最初に実行されたと想定されるため、すべての設定のデフォルト値を書き込みます。 |
| .BlockSize | 整數 | 48 | 画像処理のブロックサイズ。これは、ピクセル化された各領域の正方形のサイズです。 |
| .ShapeType | 細繩 | "Blocks" | 各ピクセル化領域の3Dオブジェクトと同じ。列挙型からキャストします。 |
| .InvertHeight | Boolean | 錯誤的 | 反転高さ/サイズ決定フラグ。 |
| .HeightSource | 細繩 | “亮度” | 高さ/サイズを決定するために使用するカラーチャンネル。列挙型からキャストします。 |
| .ImageSizeConstraints | 細繩 | “中等的” | パフォーマンス上の理由から、処理する前に行う画像のサイズの縮小量を決定します。列挙型からキャストします。実行時に解釈される実際の値。 |
| .VerticalExaggeration | 細繩 | “中等的” | 3D形状を押し出しまたは拡大するときに実行する垂直方向の誇張の量。列挙型からキャストします。 |
| .InputQuality | 整數 | 2 | 入力品質を示す値。 0から3の範囲で、3が最高品質(および処理が最も遅い)です。 |
| .CurrentCamera | 細繩 | “後退” | 最後に使用したカメラの位置。前面または背面。列挙型からキャストします。 |
| .LightColor | 細繩 | “白色的” | ライトの色の名前。列挙型からキャストします。後でカラーライブラリタイプの色に変換できます。 |
| .LightType | 細繩 | "Omni" | シーンの照明に使用されるライトのタイプの名前。列挙型からキャストします。 |
| .LightIntensity | 細繩 | “普通的” | シーンを照らすために使用される光の強度。実行時に決定される実際の値。列挙型からキャストします。 |
| .FieldOfView | 細繩 | “普通的” | カメラの視野。実際の値は実行時に決定されます。列挙型からキャストします。 |
| .ShowHistogram | Boolean | 錯誤的 | ヒストグラム表示を表示します。現在実装されていません。 |
| .HistogramBucketCount | 整數 | 256 | ヒストグラム表示の色数。現在実装されていません。 |
| .InitialView | 細繩 | "LiveView" | ユーザーが最後に表示したビュー(ライブビュー、アルバムなど)。 |
| .FullyExtrudeLetters | Boolean | 真的 | 文字が完全に押し出されるか、部分的にのみ押し出されるかを決定します。 |
| .LetterSmoothness | 細繩 | “光滑的” | 文字の曲線をどれだけスムーズに作成するかを決定します。高品質の曲線には、大きなパフォーマンスコストがかかります。実行時に決定される実際の値。列挙型からキャストします。 |
| .LetterFont | 細繩 | "Futura" | 押し出された文字のレンダリングに使用するフォント(およびオプションの太さ)。フォントがシステムに存在しない場合、BlockCamは未定義の状態に入ります。 |
| .RandomCharacterSource | 細繩 | “拉丁” | 文字を押し出すときにランダムな文字のソースとして使用する名前付きUnicode範囲。複数の範囲を指定するには、それぞれをコンマで区切ります。 |
| .VideoFPS | 整數 | 1 | 現在使用されていません。 |
| .VideoDimensions | 細繩 | "Smallest" | ビデオを生成するときの最終的なビデオサイズを決定します。実行時に決定される実際の値。列挙型からキャストします。 |
| .VideoBlockSize | 整數 | 48 | ビデオ処理のブロックサイズ。これは、ピクセル化された各領域の正方形のサイズです。 |
| .UseMetal | Boolean | 真的 | OpenGLではなくMetalを使用するようにBlockCamに指示するフラグ。 |
| .AntialiasingMode | 整數 | 0 | アンチエイリアスモードを決定します。 |
| .InitialBestFit | Boolean | 錯誤的 | trueの場合、BlockCamは、すべてのノードをビューにできるだけ厳密に合わせようとします。 |
| .SaveOriginalImageAction | 細繩 | “總是” | 元の画像を保存する方法とタイミングを決定します。列挙型からキャストします。 |
| .NextSequentialInteger | 整數 | 0 | ファイル名の生成に使用。 |
| .LoopSequentialIntegerAfter | 整數 | 9999 | 連続する整数を使用する場合、いつループを開始するかを決定します。 |
| .StartSequentialIntegerAt | 整數 | 1 | 連続整数の開始値。 |
| .IncreaseStarApexesWithProminence | Boolean | 錯誤的 | trueの場合、星形の頂点の数は色の高さが顕著になるにつれて増加します。 |
| .StarApexCount | 整數 | 5 | 星の頂点の数。 .IncreaseStarApexesWithProminenceがtrueの場合、これは頂点の開始数です。 |
| .HaltWhenCriticalThermal | Boolean | 真的 | trueの場合、BlockCamは重大な温度アラートを受信すると停止します( fatalError呼び出しを介して)。これはAppleのガイドラインに違反する可能性があり、削除される可能性があります。 |
| .HaltOnLowPower | Boolean | 真的 | trueの場合、BlockCamは低電力アラートを受信すると停止します( fatalError呼び出しを介して)。これはAppleのガイドラインに違反する可能性があり、削除される可能性があります。 |
| .BestFitOffset | 雙倍的 | 2.0 | .InitialBestFitがtrueの場合にカメラを後退させて、画像にもう少しネガティブなスペースを与えるために使用する値。 |
| .LightingModel | 細繩 | "Phong" | 表面マテリアル照明モデル。列挙型からキャストします。 |
| .CappedLineBallLocation | 細繩 | “頂部” | CappedLine形状のノードのボール(「キャップ」)の位置。列挙型からキャストします。 |
| .LoggingEnabled | Boolean | 錯誤的 | ロギングフラグを有効にします。 |
| .FontSize | 整數 | 36 | 押し出された文字のフォントサイズ。 |
| .EnableUISounds | Boolean | 真的 | Flagは、UIサウンドを再生します(ボタンが押されたときなど)。 この値が「false」の場合、他のすべてのサウンドフラグは無視されます。 |
| .EnableShutterSound | Boolean | 錯誤的 | Flagは、カメラボタンが押されたときにシャッター音を再生します。 一部の地理的な場所では、これは常に発生し、この値を設定しても効果はありません。 |
| .EnableImageProcessingSound | Boolean | 真的 | Flagは、画像処理の開始時と終了時に音声を再生します。 画像処理には時間がかかるため、ユーザーは画像がいつ完成するかを理解するのに役立ちます。 |
| .EnableVideoRecordingSound | Boolean | 真的 | ユーザーがビデオの記録を開始および停止したときに音を再生するフラグ。 |
| .EnableButtonPressSounds | Boolean | 真的 | ユーザーがボタンを押したときに音を再生するフラグ。 |
| .EnableOptionSelectSounds | Boolean | 真的 | ユーザーが画面上の設定画面でオプションを選択したときに音を再生するフラグ。 |
| .EnableCrashSounds | Boolean | 錯誤的 | フラグは、クラッシュダイアログが表示されたときにサウンドを再生します。 #DEBUGモードでコンパイルされた場合のみ有効です。 |
| .MeshDotSize | 細繩 | “中等的” | メッシュの中心ドットのサイズ。 .Noneが使用される場合、中央のドットは表示されません。 列挙型からキャストします。 |
| .MeshLineThickness | 細繩 | “中等的” | メッシュラインの太さ。 列挙型からキャストします。 |
| .RadiatingLineThickness | 細繩 | “中等的” | 放射線形状の太さ。 列挙型からキャストします。 |
| .RadiatingLineCount | 整數 | 8 | 放射ライン形状の放射ラインの数。 「4」は基線方向を指す線、「8」は基線方向とその中間、および「16」はz平面のさらに8本の線を示します。 |
| .BlockChamferSize | 細繩 | “沒有任何” | ブロック形状の面取り半径/エッジの滑らかさ。 列挙型からキャストします。 |
| .MaxImageDimension | 整數 | 1024 | 画像の最大寸法。 処理する画像が大きい場合、最長寸法がこの値になるようにサイズ変更されます。 |
| .AddUserDataToExif | Boolean | 錯誤的 | Flagは、ユーザーが作成した情報を処理済み画像のExifブロックに追加します。 |
| .使用者名稱 | 細繩 | “” | (デフォルトは空白です。)処理された画像のExifブロックに追加されるユーザー指定の名前。 これは、 .AddUserDataToExifがtrueの場合にのみ発生します。 |
| .UserCopyright | 細繩 | “” | (デフォルトは空白です。)処理された画像のExifブロックに追加されるユーザー指定の著作権文字列。 これは、 .AddUserDataToExifがtrueの場合にのみ発生します |
BlockCamは次のビジュアルをサポートしています。
現在、押し出し効果では次の形状がサポートされています(またはサポートされる予定です)。
| 形狀 | ネイティブ | メモ |
|---|---|---|
| ブロック | はい- SCNBox | Z軸に沿って長くなったネイティブボックスの形状。 |
| 三角形 | いいえ | カスタム正三角形の形状。 |
| 五角形 | いいえ | カスタム正五角形。 |
| 六角形 | いいえ | カスタム正六角形。 |
| オクトゴン | いいえ | カスタム正八角形。 |
| ピラミッド | はい- SCNPyramid | ネイティブのピラミッド形状。 |
| トロイド | はい- SCNTorus | ネイティブトーラス形状。 |
| シリンダー | はい- SCNCylinder | 自然なシリンダー形状-すてきな高架円になります。 |
| 球 | はい- SCNSphere | ネイティブの球形。 |
| カプセル | はい- SCNCapsule | ネイティブカプセルの形状。聞こえるほど面白くない。 |
| 四面体 | いいえ | カスタム正四面体ソリッド。 |
| 星 | いいえ | カスタム星形(半径方向に等しい頂点を持つ)。頂点の数を変えることができます。 |
| CombinedForRGB | はい-組み合わせ | 球体、トーラス、カプセルの組み合わせ。 |
| CombinedForHSB | はい-組み合わせ | 球体、トーラス、カプセルの組み合わせ。 |
| メッシュ | いいえ | 現在実装されていません。 |
| レター | はい- SCNText | ネイティブの押し出しテキスト。特に非ラテン系のアルファベットでは、非常に遅くなる傾向があります。 |
| 行 | はい- SCNCapsule | 非常に薄いカプセル形状。 |
| CappedLines | はい-組み合わせ | ユーザー設定に応じて、行の上部、中間、または下部に球体を配置した非常に薄いカプセル形状。 |
| RadiatingLines | はい-組み合わせ | 中心点から放射状に広がる複数の線。 ユーザーは行数を指定できます。 これはパフォーマンス重視の形状です。 |
代表的なピクセル化領域の各形状は、押し出しまたは拡大されます。押し出しの深さまたは拡大サイズの決定は、ピクセル化された領域の色に依存します。
| カラーチャンネル | 使用方法 |
|---|---|
| 色調 | 色の色相は、3Dオブジェクトの深さ/サイズを決定します。色相値は周期的であることに注意してください(0.0は基本的に1.0と同じです)。したがって、緑が強調表示されている間、赤みを帯びたピクセルは抑制される傾向があります。 |
| 彩度 | 彩度の値は深さ/サイズを決定します。明るい色は大きくなります。 |
| 明るさ | 色の明るさが深さ/サイズを決定します。これはデフォルト値であり、ほとんどの人がプログラムが機能することを期待する方法です。 |
| 赤 | 赤チャネルは深さ/サイズを決定するために使用されます。 |
| 緑 | 緑のチャネルは深さ/サイズを決定するために使用されます。 |
| 青 | 青チャンネルは深さ/サイズを決定するために使用されます。 |
| シアン | (CMYKからの)合成シアンチャンネルを使用して、深度/サイズを決定します。 |
| マゼンタ | 深さ/サイズを決定するために、CMYKからの合成マゼンタチャネルが使用されます。 |
| 黃色 | 合成の黄色チャンネル(CMYKから)を使用して深さ/サイズを決定します。 |
| 黒 | 深さ/サイズを決定するために、CMYKからの合成黒チャンネルが使用されます。 |
BlockCamは反転フラグをサポートしています。これは、ユーザーが反転を設定した場合、深度/サイズはそれ自体の比isであり、暗い領域を目立たせ、明るい領域を抑制または非表示にすることを意味します。
BlockCamは、ライトの色とライトの種類の変更をサポートしています。 色は現在、事前定義された色の小さなセットに制限されています。 ライトのタイプは、SceneKitの標準のパラメータ化されていないライト( .omniや.spotなど)に対応しています。
現在、ライトの位置はユーザーが調整することはできません。
BlockCamは、 SCNViewのallowsCameraControlフラグを使用して、ユーザーがジェスチャによって拡大、光沢、回転(3軸)できるようにします。
最初にレンダリングしたとき、結果はビューから比較的遠くにあるように見える場合があります。 BlockCamには、画像をビューに合わせるためのユーザー設定可能なフラグがあります。 この機能は、拡大と縮小に関してallowsCameraControlを混同する傾向があります。
すべてのユーザー設定(およびいくつかのプロセス設定)は、 Settingsクラスを介して保存されます。このクラスは、プログラムの残りの部分からは見えないストレージメカニズムをカプセル化します。現在、ストレージメカニズムはUserDefaultsです。設定がより複雑になった場合、これをデータベースに移行するのは簡単です。
設定にアクセスするには、呼び出し側はSettingsクラスの提供されたメソッドを使用する必要があります。これにより、データ型の整合性を確保できます。
Settingsクラスは設定レベルの変更通知も提供します(これが最初にクラスを作成する主な理由でした)。
BlockCamは3D処理を使用し、デバイスのグラフィックチップを実行します。ユーザーが最高品質の設定を指定した場合、特定の極端な条件が発生する可能性があります。デバイスを損傷から保護するために、そのような場合にBlockCamの実行を中止する設定を使用できます。
| イベント | アクション | 設定の制御 |
|---|---|---|
| 熱的 | サーマルイベントがクリティカルステージ(通知では文字通り.critical )に達すると、設定がtrueの場合、BlockCamによって作成される熱ストレスを減らす致命的なエラーが生成されます。 | .HaltWhenTooHot |
| バッテリー | バッテリーが低電力状態になった場合、設定がtrueの場合、再充電前にバッテリーの寿命を保つために致命的なエラーが生成されます。 | .HaltOnLowPower |
BlockCamの著作権©2019, 2020 by Stuart Rankin