iPhone实况照片从Windows资源管理器复制的JPG+MOV无法正常还原到iPhone

背景:

之前使用的iPhone 15 Pro,使用的Windows资源管理器当中复制导出的实况照片,复制出来的格式例如IMG_0001.JPG, IMG_0001.MOV。之后手机就卖掉了。现在使用的iPhone 14 Pro Max,想要导回之前备份的实况照片。尝试使用爱思助手导入,虽然文件名都一样,但是仍然会报错:

是不是非常可恶?

但是使用爱思助手导出实况照片、出来的也是JPG+MOV。再重新导回去,发现一切正常。这么说一定是可以导入的,肯定是哪里出了问题。

咨询了爱思助手的客服,完全不理。没办法,只好自己研究咯。


解决方法:

读取MOV的EXIF信息

exiftool -a -u -g1 IMG_4676.MOV > IMG_4676.MOV.TXT

---- Keys ----字段下面的Content Identifier键值,就是JPG需要被修改成的Media Group UUID。也就是说,实际上,他们是依据这个uuid来判断视频和照片的关联。发现爱思助手导出的JPG和MOV正好也是对应的。所以实际上,针对资源管理器复制出来的,我们只要读取MOV的这个键值,把我们从JPG当中的Media Group UUID修改成一样的即可!

# MOV
Content Identifier              : E2523D1E-7C8A-423B-A8DB-53C8A073457F# JPG
Media Group UUID                : E2523D1E-7C8A-423B-A8DB-53C8A073457F

修改JPG当中的Media Group UUID

利用010Editor,打开文件,

直接把我原始照片里面的UUID替换掉。保存,即可导入成功。

这个UUID在文件中是明文TEXT存储的,在批量处理的情况下我们可以直接写一个脚本,利用exiftool读取出来MOV文件的Content Identifier,读取JPG的Media Group UUID,然后字节流模式打开JPG,在文件当中直接执行替换即可。

批量处理代码

Windows平台,下载exiftool:

https://exiftool.org/index.html

 

下载这个stand-alone的windows版本 。

下载下来的zip里面就是一个exe文件,重命名为exiftool.exe即可。

创建下面的python文件,把exe和这个python文件放到一个目录下面。

这个代码会将成对的JPG+MOV都拷贝到一个新的文件夹里面去。这样在原始文件夹里面的文件都是需要单独导入成静态照片和普通视频的。方便导入。在爱思助手里面就直接选择程序生成的LivePhoto文件夹。

建议在运行此代码之前,把资料先备份一份,以防万一。毕竟数据无价,谨慎操作。

import subprocess
import os
import shutil
from collections import defaultdict
import redef get_exif_data(file_path):try:process = subprocess.Popen(['exiftool', '-a', '-u', '-g1', file_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)stdout, stderr = process.communicate()if process.returncode != 0:print(f"Error: {stderr.strip()}")return Nonereturn stdout.strip()except FileNotFoundError:print("ExifTool is not installed or not found in the system path.")return Nonedef replace_uuid_in_jpg(jpg_file_path, old_uuid, new_uuid):with open(jpg_file_path, 'rb+') as jpg_file:file_content = jpg_file.read()updated_content = file_content.replace(old_uuid, new_uuid)jpg_file.seek(0)jpg_file.write(updated_content)jpg_file.truncate()def fix_jpg_for_ios_import(jpg_file_path, mov_file_path):exif_data = get_exif_data(mov_file_path).split(b'\n')content_identifier = Nonefor item in exif_data:if b'Content Identifier' in item:content_identifier = item.split(b':')[-1].strip()breakassert content_identifier is not Noneassert re.match(r'[0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}', content_identifier.decode().upper())print(b'    ' + mov_file_path.encode() + b' | ' + content_identifier)exif_data = get_exif_data(jpg_file_path).split(b'\n')media_group_uuid = Nonefor item in exif_data:if b'Media Group UUID' in item or b'Content Identifier' in item:media_group_uuid = item.split(b':')[-1].strip()breakassert media_group_uuid is not Noneassert re.match(r'[0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}', media_group_uuid.decode().upper())print(b'    ' + jpg_file_path.encode() + b' | ' + media_group_uuid)replace_uuid_in_jpg(jpg_file_path, media_group_uuid, content_identifier)def get_matching_files(directory):# 字典用于存储文件名前缀及其对应的后缀file_dict = defaultdict(set)for filename in os.listdir(directory):name, ext = os.path.splitext(filename)ext = ext.upper()# 只处理JPG和MOV文件if ext in {'.JPG', '.MOV'}:file_dict[name].add(ext)# 找到同时具有JPG和MOV后缀的文件名前缀matching_files = [name for name, exts in file_dict.items() if {'.JPG', '.MOV'} <= exts]return matching_filesif __name__ == '__main__':jpg_mov_path = 'I:/iPhone15Pro/202310__'file_prefixes = get_matching_files(jpg_mov_path)if not os.path.exists(os.path.join(jpg_mov_path, "LivePhoto")):os.mkdir(os.path.join(jpg_mov_path, "LivePhoto"))for file_prefix in file_prefixes:dst_jpg_path = os.path.join(jpg_mov_path, "LivePhoto", f"{file_prefix}.JPG")dst_mov_path = os.path.join(jpg_mov_path, "LivePhoto", f"{file_prefix}.MOV")shutil.move(os.path.join(jpg_mov_path, f"{file_prefix}.JPG"), dst_jpg_path)shutil.move(os.path.join(jpg_mov_path, f"{file_prefix}.MOV"), dst_mov_path)fix_jpg_for_ios_import(dst_jpg_path, dst_mov_path)

尝试过的方法

先用手上的iPhone 14 Pro Max随便拍两张照片,一个通过爱思导出,一个通过Windows资源管理器复制。对比一下出来的文件

很明显这两个文件大小差距很大。

MOV的话,文件大小一样,算了一下md5也一样。说明问题不在MOV上,JPG有问题。

先启动WSL,用binwalk,foremost看一下:

binwalk IMG_4676.JPGDECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
34            0x22            TIFF image data, big-endian, offset of first image directory: 8
2828          0xB0C           TIFF image data, big-endian, offset of first image directory: 8
2214234       0x21C95A        TIFF image data, big-endian, offset of first image directory: 8
binwalk 2024_05_22_12_44_IMG_4676.JPGDECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
30            0x1E            TIFF image data, big-endian, offset of first image directory: 8

foremost解出来两张图片。一张是全彩的正常图片(00000000.jpg),携带大量有效metadata(例如拍摄机型、时间、GPS等)。另一张点开直接看到的是灰度图像,没有看到有效的metadata。

修改文件名对应MOV,导入00000000.jpg也失败。

那么就用exiftool看一下。

exiftool -a -u -g1 IMG_4676.JPG > IMG_4676_bad.TXT
exiftool -a -u -g1 2024_05_22_12_44_IMG_4676.JPG > 2024_05_22_12_44_IMG_4676.JPG.TXT

使用Beyond Compare对比一下哪里出问题了。

存在大量不同。尤其是MP系列字段。因为本身存在2张照片

先不管MPF0字段。先尝试直接利用exiftool复制爱思助手导出图片的exif信息,直接覆盖过去:

exiftool -TagsFromFile 2024_05_22_12_44_IMG_4676.JPG -all:all IMG_4676.JPG

直接成功了!

说明只需要修改这里面不同的EXIF信息即可修复导入! 

尝试单独修改了几个项目,导入,无果。最终把目光看向了Apple字段下面的Media Group UUID

但是这个项目还不太好改,询问GPT,下面这个方法不好用。

exiftool -Apple:MediaGroupUUID="E2523D1E-7C8A-423B-A8DB-53C8A073457F" IMG_4676.JPG
Warning: [minor] Maker notes could not be parsed - IMG_4676.JPG0 image files updated1 image files unchanged

 尝试了其他的命令行修改的方法也不行。只能从文件实际内容去修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/331141.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VBA即用型代码手册:删除Excel中空白行Delete Blank Rows in Excel

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

一篇文章讲透排序算法之希尔排序

希尔排序是对插入排序的优化&#xff0c;如果你不了解插入排序的话&#xff0c;可以先阅读这篇文章&#xff1a;插入排序 目录 1.插入排序的问题 2.希尔排序的思路 3.希尔排序的实现 4.希尔排序的优化 5.希尔排序的时间复杂度 1.插入排序的问题 如果用插入排序对一个逆序…

单片机设计注意事项

1.电源线可以30mil走线&#xff0c;信号线可以6mil走线 2.LDO推荐 SGM2019-3.3,RT9013,RT9193,1117-3.3V。 3.单片机VCC要充分滤波后再供电&#xff0c;可以接0.1uf的电容 4.晶振附件不要走其他元件&#xff0c;且放置完单片机后就放置晶振&#xff0c;晶振靠近X1,X2。

SpringBoot高级原理详解

文章目录 1 SpringBoot自动化配置原理01-SpringBoot2高级-starter依赖管理机制02-SpringBoot2高级-自动化配置初体验03-SpringBoot2高级-底层原理-Configuration配置注解04-SpringBoot2高级-底层原理-Import注解使用105-SpringBoot2高级-底层原理-Import注解使用206-SpringBoot…

微信小程序上线必备:SSL证书申请以及安装

一、认识ssl证书 1、ssl证书是什么&#xff1f; SSL证书&#xff0c;全称Secure Socket Layer Certificate&#xff0c;是一种数字证书&#xff0c;它遵循SSL&#xff08;现在通常指TLS&#xff0c;Transport Layer Security&#xff09;协议标准&#xff0c;用于在客户端&…

打造AI虚拟伴侣 - 优化方案

第一部分:框架优化概述 1、精确定位: 构建一个高度灵活且用户友好的平台,旨在通过无缝集成多种大型语言模型(LLMs)后端,为用户创造沉浸式的角色交互体验。不仅适配电脑端,还特别优化移动端体验,满足二次元AI虚拟伴侣市场的特定需求。 2、核心功能强化: 增强后端兼容…

k8s——Pod详解

一、Pod基础概念 1.1 Pod定义 Pod是kubernetes中最小的资源管理组件&#xff0c;Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的&#xff0c;例如&#xff0c;用于管理Pod运行…

华为云服务培训

一、存储类服务实践 是什么&#xff1a; 云硬盘( Elastic Volume Service )是一种为 ECS&#xff08;弹性云服务器&#xff09;、BMS&#xff08;裸金属服务器&#xff09; 等计算服务提供持久性存储的服务。 作用&#xff1a; 它通过数据冗余和缓存加速等多项技术&#xf…

【C++高阶(一)】继承

目录 一、继承的概念 1.继承的基本概念 2.继承的定义和语法 3.继承基类成员访问方式的变化 ​编辑 4.总结 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 1.派生类中的默认构造函数 2.派生类中的拷贝构造函数 3.派生类中的移动构造函数…

[国产大模型简单使用介绍] 开源与免费API

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 随着大模型技术蓬勃发展和开源社区越来越活跃,国内的大模型也如雨后春笋一般.这时,一些就会问了,有了llama3,Mistral还有Gemma等等,国外大厂接连发力,一些开源社区也会有一些不错的模型,国内怎么比?对一个人使用,oll…

02.爬虫---HTTP基本原理

02.HTTP基本原理 1.URI 和 URL 的区别2.HTTP 和 HTTPS 的区别3.请求过程 1.URI 和 URL 的区别 URL&#xff08;Uniform Resource Locator&#xff09;即-统一资源定位符 URL是用来定位和访问互联网上资源的独特标识&#xff0c;它包括了资源的位置&#xff08;如IP地址或域名&a…

node.js —— 解读http模块

目录 http模块&#xff1a; http模块的引入&#xff1a; 创建web服务器的基本步骤&#xff1a; web服务器的一些基本属性&#xff1a; 上述知识汇总案例&#xff1a; http模块&#xff1a; http模块的引入&#xff1a; const http require (http) 创建web服务器的基本步骤…

记录docker ps查找指定容器的几个命令

1.docker ps | grep registry 查询包含registry的容器 2.docker ps | grep -E "reigistry\s" 开启正则匹配模式&#xff0c;匹配registry后面为空格的容器&#xff0c;若是匹配一整行可以这样写docker ps | grep -E "^([0-9a-f]{12})\sregistry\s.*" 这…

第八节 条件装配案例讲解

一、条件装配的作用是什么 条件装配是 Spring 框架中一个强大的特性&#xff0c;使得开发者能够创建更加灵活和可维护的应用程序。在 Spring Boot 中&#xff0c;这个特性被大量用于自动配置&#xff0c;极大地简化了基于 Spring 的应用开发。 二、条件装配注解 <dependen…

Android-自定义三角形评分控件

效果图 序言 在移动应用开发中&#xff0c;显示数据的方式多种多样&#xff0c;直观的图形展示常常能带给用户更好的体验。本文将介绍如何使用Flutter创建一个自定义三角形纬度评分控件&#xff0c;该控件可以通过动画展示评分的变化&#xff0c;让应用界面更加生动。 实现思…

Vue3实战easypan(六):回收站+设置

一、回收站 src/views/recycle/Recycle.vue <template><!-- 上方两个按钮 --><div class"top"><el-button type"success" :disabled"selectFileIdList.length 0" click"revertBatch"><span class"ic…

[保姆式教程]使用目标检测模型YOLO V8 OBB进行旋转目标的检测:训练自己的数据集(基于卫星和无人机的农业大棚数据集)

最近需要做基于卫星和无人机的农业大棚的旋转目标检测&#xff0c;基于YOLO V8 OBB的原因是因为尝试的第二个模型就是YOLO V8&#xff0c;后面会基于YOLO V9模型做农业大棚的旋转目标检测。YOLO V9目前还不能进行旋转目标的检测&#xff0c;需要修改代码 PS:欢迎大家分享农业大…

Plotly库利用滑块创建数据可视化

使用了Plotly库来创建一个数据可视化图表&#xff0c;并使用滑块来控制显示哪些数据 import plotly.graph_objects as go from plotly.subplots import make_subplots# 示例数据 x [1, 2, 3, 4, 5] y1 [1, 2, 3, 4, 5] y2 [5, 4, 3, 2, 1] y3 [2, 3, 1, 5, 4]# 创建子图 f…

12306技术内幕

公司内部做的一次技术分享 文章目录 12306的成就12306系统特点12306系统难点解决思路产品角度技术角度余票库存的表如何设计&#xff1f; 抢票软件推荐巨人的肩膀 对于未公开的技术部分&#xff0c;只能结合已公开的信息&#xff0c;去做大胆的猜想。 本文提到的一些解决方案&…

【车载开发系列】Autosar中的VFB

【车载开发系列】Autosar中的VFB # 【车载开发系列】Autosar中的VFB 【车载开发系列】Autosar中的VFB一. 什么是VFB二. VFB的优点与缺点1&#xff09;VFB的缺点2&#xff09;VFB的好处 三. RTE与VFB之间关系四. 总线架构模式 一. 什么是VFB Virtual Functional Bus。它就是虚拟…