OpenCV寫入圖像文件到iOS設備沙盒

今天遇到一個OpenCV的坑,其本身不是OpenCV造成的,而是是偉大的蘋果,以及其封閉的系統。這個坑使得存儲圖像文件的過程多費周章,曲折難解。

在OpenCV中,寫入圖像文件,只需要用imwrite函數:

cv::imwrite(imageName, img);

在Android系統中,在獲取相冊存儲權限的條件下,以上方法即可很容易地將img對象中的圖像文件存儲到系統相冊中,無需做過多處理。

然而,在iOS系統中,只傳入imageNamecv::Matimg是無任何作用的,該方法執行成功,卻不見效果。而將cv::Mat轉化成UIImage類型,再存儲到沙盒中的方式也不失為比較好的方法,但缺點是它會導致一些意想不到的問題。

在我的實踐中,問題如下:

  • 圖片所占存儲空間變小(原圖為3+MB,只做讀取并轉化成UIImage后僅500+K)
  • 顏色錯誤,原本紅色的實木家具變成了棕色,淺黃色的地板變成了藍色(不知其然,所用cv::Mat --> UIImage方法為OpenCV官方文檔中方法)

經過一下午的問題排查,終尋求方法將原圖像文件無差別寫入iOS設備沙盒中,實現過程:

bool writeImage2Document(const char *imageName, cv::Mat img) {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"/%s", imageName]];
    const char* cPath = [filePath cStringUsingEncoding:NSMacOSRomanStringEncoding];
    
    const cv::String newPaths = (const cv::String)cPath;
    
    //Save as Bitmap to Documents-Directory
    cv::imwrite(newPaths, img);
    return true;
}

這里的路徑經過三次轉化,才得到imwrite函數在iOS系統中有用的參數,實在令人汗顏,其中NSMacOSRomanStringEncoding就是用MacOS的特殊編碼方式對路徑進行編碼,再強轉為cv::String才能作為有效的參數,至于為什么這么轉來轉去,誰知道呢!

今日記錄于此,留與后人吐槽!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容