Powershell:将 iPhone 相机图像复制到计算机,与屏幕截图等分开

Powershell:将 iPhone 相机图像复制到计算机,与屏幕截图等分开

我想要半自动地将 DCIM 文件从我的 iPhone 复制并分类到我的电脑上,将“相关”的相机图像放在一起并与屏幕截图、下载的 jpeg、gif、mpeg、png 等分开。

我的 iPhone 上有一堆下载的图片(来自 Pinterest、Tumblr 等)。我还用 iPhone 相机拍摄了一堆相关的 jpg/mp4 图片,这些图片成对拍摄,按文件名顺序一个接一个。显然,iPhone 相机会为每张照片录制 jpeg 图像和多帧 mp4 影片。下载的图像只是单个 jpeg、gif、mp4 等。

我希望脚本驻留在本地计算机上,并在 iPhone 安装后手动运行。

iPhone 图像路径为:'mtp://Scottc 的 iPhone/内部存储/DCIM/291APPLE', 'mtp://Scottc 的 iPhone/内部存储/DCIM/292APPLE', 'mtp://Scottc 的 iPhone/内部存储/DCIM/293APPLE',ETC。

我无法控制子目录名称(例如291苹果,292苹果,293苹果等,但它们总是以(看似随机的)3 位数字开头,并以“APPLE”结尾。可以有一个或十个。这取决于 iOS 和文件数量。子目录是只读的,但文件本身是可读写的,因此可以稍后删除。

因此,我需要递归处理所有文件,直到'mtp://Scottc 的 iPhone/内部存储/DCIM/'

iPhone 上每个子文件夹中的目录列表如下所示:

*image001.jpg* <-- downloaded *image002.jpg* <-- downloaded *image003.jpg* <-- camera image a *image004.mp4* <-- camera image b *image005.jpg* <-- downloaded *image006.jpg* <-- downloaded *image007.jpg* <-- downloaded *image008.jpg* <-- downloaded *image009.jpg* <-- camera image a *image010.mp4* <-- camera image b *image011.jpg* <-- downloaded

因此文件 003 和 004 是相关的,文件 009 和 010 也是相关的。Scottc 的 iPhone/DCIM/* 中的所有文件都有唯一的名称。

我只想将相关图像复制到目录 A,将剩余图像(下载,可以是任何类型 jpg、gif、mp4 等)复制到目录 B。

有人能帮我解释一下实现这个功能的 Powershell 逻辑和代码吗?我真的不知道该怎么做。也许有更好的方法或有人已经写好的实用程序?如果是这样,我一直找不到,而且一次处理数百张图像真的很繁琐。这似乎是 Powershell 的完美应用程序。

思考我需要循环遍历文件,识别第一个 *.mp4 文件,将文件名放入变量中,将 *.mp4 文件复制到目录 A,然后从变量中减去值 1 以按字母顺序匹配前面的相关 *.jpg 文件名并将其复制到目录 A。

冲洗并重复。

然后将剩余的不相关文件(任何类型)复制到目录 B。

因此,最终我得到了以下目录结构:

On the iPhone:  

(leave the original files as is)  

Directory A  

image003.jpg    <-- camera image a  
image004.mp4    <-- camera image b  
image009.jpg    <-- camera image a  
image010.mp4    <-- camera image b  

Directory B  

image001.jpg    <-- downloaded  
image002.jpg    <-- downloaded  
image005.jpg    <-- downloaded  
image006.jpg    <-- downloaded  
image007.jpg    <-- downloaded  
image008.jpg    <-- downloaded  
image011.jpg    <-- downloaded 

最后,询问用户是否要删除 iPhone 原始文件(我想我可以处理这部分)但不删除 iPhone 目录(上面提到的权限问题……iOS 会处理目录结构)。

我认为一个问题就是,下载的以 *.mp4 结尾的电影将与之前下载的不相关的 *.jpg 文件匹配。除非有人有巧妙的方法来处理这个问题。我可以忍受这个小小的限制。我注意到相关的 jpg/mp4 文件具有相同的 hh:ss 时间戳,如果这有帮助的话。下载的图像/电影/gif 从来都不匹配时间。也许匹配时间戳更容易?也不知道如何实现。

我真正感到困惑的是文件名变量的处理,数学-1处理文件名时的逻辑以及如何处理剩余的文件名(在数组中,还是通过迭代?)。复制、移动、名称匹配等。我想我可以通过反复试验来解决——但请随意详细说明。有些人可以即时完成的事情需要我几个小时,经常以失败和沮丧告终 :-(

有人能帮忙吗?我的 Powershell 技能只达到第 3 章左右,所以我真的很挣扎。

答案1

这有点晚了,但我针对 iPhone 的特定子文件夹对这个脚本进行了一些调整: https://blog.daiyanyingyu.uk/2018/03/20/powershell-mtp/

与原始脚本不同的是最后一部分,现在循环遍历DCIM文件夹中的子文件夹。然后,此脚本移动将所有文件复制到目标。它没有直接回答您的问题,但至少解决了 MTP 驱动器部分。更改:

$items = @( $folder.GetFolder.items() | where { $_.Name -match $filter } )

$subfolders = $folder.GetFolder.items()
foreach ($subfolder in $subfolders) {
    $items = @( $subfolder.GetFolder.items() | where { $_.Name -match $filter } )

}当然最后还会有一个额外的。

更改后的使用示例:

./mptcopy.ps1 -phoneName 'Apple iPhone' -sourceFolder '\Internal Storage\DCIM' -targetFolder 'C:\pics' -filter '(.jpg)|(.jpeg)|(.png)|(.gif)|(.bmp)'

答案2

尝试一下,并让我们知道它是否有效:

编辑:我忘了搜索每个目录。现在应该修复了。

$directoryA = "%userprofile%\Pictures\Directory A"
$directoryB = "%userprofile%\Pictures\Directory B"
$items = Get-ChildItem ".\\image*"  -Recurse | ForEach-Object { if (!($_.PSIsContainer)) { $_}}
$i = 0
$mp4s = @()
$associatedImgs = @()
 ForEach($item in $items) {
    If(($items[$items.IndexOf($item)].Extension).Equals(".mp4")) {
        $mp4s += $i
        $associatedImgs += $i - 1
        }
    $i += 1
}

ForEach($mp4 in $mp4s) {
    Copy-Item -Path $items[$mp4].FullName -Destination $directoryA -Force -PassThru -Verbose
    Copy-Item -Path $items[$mp4 - 1].FullName -Destination $directoryA -Force -PassThru -Verbose

}
ForEach($item in $items) {
    If($mp4s.Contains($items.IndexOf($item))){

    } ElseIf($associatedImgs.Contains($items.IndexOf($item))) {

    } Else {
        Copy-Item -Path $items[$item].FullName -Destination $directoryB -Force -PassThru -Verbose

    }
}

答案3

.mp4如果/对的创建时间.jpg可靠,
您可以尝试根据此属性对文件进行分组:

Get-ChildItem -Recurse -include '*.htm','*.ps1'|
  Group-Object Creationtime|
    ForEach-Object {If($_.Group.Count -eq 2){$_.Group.Fullname;"---"}}

这将仅输出两个匹配的时间对以供检查。

相关内容