[英]Read image on iPhone from C++
I am working on a C++ library that shall do image processing.我正在研究一个应该进行图像处理的 C++ 库。 My approach now is to pass two strings to C++ from swift.
我现在的方法是将两个字符串从 swift 传递给 C++。 One string is the path to the image and the second is the output directory.
第一个字符串是图像的路径,第二个字符串是 output 目录。
All the time I get that the file does not exist.我一直认为该文件不存在。 How can I get the correct path the asset?
如何获得资产的正确路径? The image lies in a directory I have created on my own and is called "test.jpg".
该图像位于我自己创建的目录中,名为“test.jpg”。 I also have a "test2.jpg" in Assets.
我在资产中也有一个“test2.jpg”。 Have not managed to find that either.
也没有设法找到。
Swift Code: Swift 代码:
func getGrayImage() -> Image {
if var resourcePath = Bundle.main.url(forResource: "test", withExtension: "jpg") {
let dir = resourcePath.deletingLastPathComponent()
VideoProcessingWrapper().rgb2gray(resourcePath.absoluteString, dir.absoluteString)
}
return Image("test2")
}
C++ Code: C++ 代码:
void VideoProcessing::rgb2gray(const std::string& image_path, const std::string& dir) {
std::cout << "C++: " << std::endl;
std::cout << image_path << std::endl;
std::cout << std::endl;
std::cout << dir << std::endl;
std::cout << "In directory: " <<std::endl;
for (const auto& entry : std::filesystem::directory_iterator(dir)) {
std::cout << entry.path() << std::endl;
}
if (std::filesystem::exists(image_path)) {
std::cout << "File exists" << std::endl;
} else {
std::cout << "File does NOT exist" << std::endl;
return;
}
cv::imread(image_path, cv::IMREAD_COLOR);
}
It even crashes when trying to display all files in the directory, stating that the directory does not exist.它甚至在尝试显示目录中的所有文件时崩溃,说明该目录不存在。 But what have I then been given from
Bundle.main.url
-call?但是,我从
Bundle.main.url
调用中得到了什么?
This is the printout from the C++ function using a simulator:这是 C++ function 使用模拟器的打印输出:
C++:
file:///Users/name/Library/Developer/CoreSimulator/Devices/7F438661-8BF5-4A60-B41F-1D4B7FEC6A8E/data/Containers/Bundle/Application/AB3EFF3E-79A4-469C-A3BF-ABDD31A09E61/TestVideoProcess.app/test.jpg
file:///Users/name/Library/Developer/CoreSimulator/Devices/7F438661-8BF5-4A60-B41F-1D4B7FEC6A8E/data/Containers/Bundle/Application/AB3EFF3E-79A4-469C-A3BF-ABDD31A09E61/TestVideoProcess.app/
I get the same behaviour when running on a real iPhone.在真正的 iPhone 上运行时,我得到了相同的行为。
The problem here is that Foundation
framework represent paths with URI 's, while C++ standard library filesystem relies on more file-path-specific format which may consist of only the following components :这里的问题是
Foundation
框架用URI表示路径,而 C++ 标准库文件系统依赖于更多的文件路径特定格式,它可能仅包含以下组件:
root-name(optional)
: identifies the root on a filesystem with multiple roots (such as"C:"
or"//myserver"
).root-name(optional)
:标识具有多个根的文件系统上的根(例如"C:"
或"//myserver"
)。 In case of ambiguity, the longest sequence of characters that forms a valid root-name is treated as the root-name.在有歧义的情况下,将 forms 有效根名称的最长字符序列视为根名称。 The standard library may define additional root-names besides the ones understood by the OS API.
除了 OS API 理解的根名称之外,标准库还可以定义其他根名称。
root-directory(optional)
: a directory separator that, if present, marks this path as absolute.root-directory(optional)
:一个目录分隔符,如果存在,则将此路径标记为绝对路径。 If it is missing (and the first element other than the root name is a file name), then the path is relative and requires another path as the starting location to resolve to a file name.如果它丢失(并且除根名称之外的第一个元素是文件名),则路径是相对的,并且需要另一个路径作为起始位置才能解析为文件名。
- Zero or more of the following:
以下零个或多个:
file-name
: sequence of characters that aren't directory separators or preferred directory separators (additional limitations may be imposed by the OS or file system).file-name
:不是目录分隔符或首选目录分隔符的字符序列(操作系统或文件系统可能会施加额外的限制)。 This name may identify a file, a hard link, a symbolic link, or a directory.此名称可以标识文件、硬链接、符号链接或目录。 Two special file-names are recognized:
可以识别两个特殊的文件名:
dot
: the file name consisting of a single dot character.
dot
:由单个点字符组成的文件名.
is a directory name that refers to the current directory dot-dot: the file name consisting of two dot characters..
is a directory name that refers to the parent directory.是指当前目录的目录名 dot-dot:由两个点字符组成的文件名
..
是指父目录的目录名。directory-separators
: the forward slash character/
or the alternative character provided as path::preferred_separator.directory-separators
:正斜杠字符/
或作为 path::preferred_separator 提供的替代字符。 If this character is repeated, it is treated as a single directory separator:/usr///////lib
is the same as/usr/lib
如果此字符重复,则将其视为单个目录分隔符:
/usr///////lib
与/usr/lib
相同
From the rules above I can conclude that the difference of a path from URI is at least that the latter contains scheme
.从上面的规则我可以得出结论,路径与 URI 的区别至少在于后者包含
scheme
。 One trick you can refer to is to build the path from pathComponents
of the URL
class:您可以参考的一个技巧是从
pathComponents
的URL
构建路径:
if let resourcePath = Bundle.main.url(forResource: "test", withExtension: "jpg") {
let dir = resourcePath.deletingLastPathComponent()
VideoProcessingWrapper().rgb2gray(resourcePath.pathComponents.joined(separator: "/"),
dir.pathComponents.joined(separator: "/"))
}
Alternatively, as suggested by mani in the comments of your question , you can use the path
property of the same class, but for some reason it's now deprecated.或者,正如mani在您的问题的评论中所建议的那样,您可以使用同一 class 的
path
属性,但由于某种原因,它现在已被弃用。
No matter what you do, the bundle directory is inside your application and you have no write access to it.无论您做什么,bundle 目录都在您的应用程序中,您对它没有写入权限。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.