从 Windows 相机获取文件位置和名称

Get file location and names from Windows Camera

我 运行 在使用 QCamera 对焦和其他东西时遇到了麻烦,所以我想我可以使用 Windows 10 提供的相机软件。基于 opening the Windows Camera I did some trials to aquire the taken images and use them for my program. In the documentation 的线程及其 API 我没有找到可用的片段(对我来说),所以我创建了下面提到的 hack。它假定图像位于注册表中提到的 目标文件夹 'C:\Users\*username*\Pictures\Camera Roll' 中(见下文),但我不知道这是否可靠或如何获得正确的键名。 我不认为这是唯一和最干净的解决方案。所以,我的问题是如何获取拍摄的图像和 open/close 相机本身? 实际上该函数会等到 'WindowsCamera.exe' 离开进程列表并且 return 在 目标文件夹

中新添加图像/视频

在注册表中我发现:

条目:Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders 目标文件夹 的密钥名称为 {3B193882-D3AD-4eab-965A-69829D1FB59F}。我觉得这把钥匙没用。

我的 hack 的工作示例:

import subprocess
import pathlib
import psutil

def check_for_files(path, pattern):
    print(" check_for_files:", (path, pattern))
    files = []
    for filename in pathlib.Path(path).rglob(pattern):
        files.append (filename)
    return files

def get_Windows_Picture(picpath):
    prefiles = check_for_files(picpath, '*.jpg')
    x = subprocess.call('start microsoft.windows.camera:',  shell=True)
    processlist = [proc.info['name'] for proc in psutil.process_iter (['name'])]
    while 'WindowsCamera.exe' in processlist:
        processlist = [proc.info['name'] for proc in psutil.process_iter (['name'])]
    postfiles = check_for_files(picpath, '*.jpg')
    newfiles = []
    for file in postfiles:
        if file not in prefiles:
            newfiles.append(str(file))
    return newfiles
if __name__ == "__main__":
    picpath = str (pathlib.Path ("C:/Users/*user*/Pictures/Camera Roll"))
    images = get_Windows_Picture(picpath)
    print("Images:", images)

Camera Roll 是一个“known Windows folder”,这意味着某些 API 可以为您检索确切的路径(即使它不是默认路径):

knownfolderid 文档将为您提供所需文件夹的常量名称(在您的情况下为 FOLDERID_CameraRoll)。正如您在链接页面中看到的那样,默认值%USERPROFILE%\Pictures\Camera Roll(这是默认值,所以这并不意味着每个人都一样)。

Python 中的问题是您需要使用 ctypes,这有时会很麻烦(尤其是在您必须处理 GUID 和释放内存的情况下)由 API).

返回

这个 gist 给出了一个很好的例子,说明如何使用 ctypes 从 Python 调用 SHGetKnownFolderPath。在您的情况下,您只需要 FOLDERID class 中的 CameraRoll 成员,这样您就可以大大简化代码。

旁注:不要轮询进程结束,只需在 Popen 对象上使用 wait() 函数。