之前一直使用的piwigo,有很多的问题,而且呢,也不美观,piwigo教程就自行百度吧,这个比较简单。

偶然之间找到一个代替品,感觉挺好的。

那就是PhotoPrism

啥也不说,先看效果

查看所有照片
所有视频
瞬间
日历
我最喜欢的地图功能
自动生成的标签
还有就是不破坏原文件结构

安装

直接app就可以搜到

配置

然后就可以打开了,不需要配置什么东西,修改成中文后自行设置。

先修改成中文

然后就着重说一下同步。

手机自动同步到Nas

直接app搜索syncthing,配置如下:

syncthing配置

然后点击添加文件夹

文件夹标签可以说是一个备注

注意下面的文件夹路径,如果是自己映射的,要改成自己映射的名称。

然后手机下载一个手机版,官网,需要梯子,自备。

电脑上打开操作,显示ID

手机打开后,直接点击设备,扫一扫,然后填写备注,点击右上角对号

电脑上同意一下即可。

然后点击选项

共享中勾选刚刚共享的用户

高级中更改文件夹类型为仅接收。

然后点击保存即可。

手机端点击网页管理页面

然后会提示有共享目录,点击添加。

然后同样进行修改。

高级中修改为,仅发送。

配置一下文件夹路径

我这里选择的是相机目录,自动同步照片和视频

到这里自动同步已经完成了。

下面做一个照片自动分类的。

自动将照片按照拍照地点,放到对应的目录。

一下是py代码,用来自动解析图片位置并进行文件移动。

'''
本文件用来批量根据照片属性对照片进行分类
输入文件夹
输出根据省市区进行分类的文件结构
会跳过没有经纬度的照片
'''




import requests
import exifread
import time
import os
import shutil
import sys


class GetPhotoInfo:
    def __init__(self, photo):
        self.photo = photo
        # 百度地图ak  请替换为自己申请的ak
        self.ak = 'nYPs4LQ9a4VhVxj55AD69K6zgsRy9o4z'
        self.location = self.get_photo_info()

    def get_photo_info(self, ):
        print('当前解析文件路径:{}'.format(self.photo))
        try:
            with open(self.photo, 'rb') as f:
                tags = exifread.process_file(f)

            # 打印照片其中一些信息
            # print('拍摄时间:', tags['EXIF DateTimeOriginal'])
            # print('照相机制造商:', tags['Image Make'])
            # print('照相机型号:', tags['Image Model'])
            # print('照片尺寸:', tags['EXIF ExifImageWidth'], tags['EXIF ExifImageLength'])
            # 纬度
            lat_ref = tags["GPS GPSLatitudeRef"].printable
            lat = tags["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
            if len(lat) < 4:
                return None
            lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
            if lat_ref != "N":
                lat = lat * (-1)
            # 经度
            lon_ref = tags["GPS GPSLongitudeRef"].printable
            lon = tags["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
            if len(lon) < 4:
                return None
            lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600
            if lon_ref != "E":
                lon = lon * (-1)
        except KeyError:
            # print("ERROR:请确保照片包含经纬度等EXIF信息。\n")
            return None
        else:
            # print("经纬度:", lat, lon)
            return lat, lon

    def get_location(self):
        if self.location is None:
            return
        url = 'http://api.map.baidu.com/reverse_geocoding/v3/?ak={}&output=json' \
              '&coordtype=wgs84ll&location={},{}'.format(self.ak, *self.location)
        response = requests.get(url).json()
        status = response['status']
        if status == 0:
            address = response['result']['formatted_address']
            print('详细地址:', address)
        else:
            print('baidu_map error')

        provinceidx = address.find("省")
        province = "未知"
        if provinceidx > 0:
            province = address[0:provinceidx+1]
            address = address[provinceidx+1:]

        city = "未知"
        cityidx = address.find("市")
        if cityidx > 0:
            city = address[0:cityidx+1]
            address = address[cityidx+1:]

        area = "未知"
        areaidx = address.find("区")
        if areaidx > 0:
            area = address[0: areaidx + 1]
            address = address[areaidx + 1:]
        else:
            areaidx = address.find("县")
            if areaidx > 0:
                area = address[0:areaidx + 1]
                address = address[areaidx + 1:]
            else:
                areaidx = address.find("市")
                if areaidx > 0:
                    area = address[0: areaidx + 1]
                    address = address[areaidx + 1:]

        detail = address
        decompose = [province, city, area, detail]  # 分解后的地址
        return decompose


def get_all_path(file_path):
    all_file_name = []
    for maindir, subdir, file_name_list in os.walk(file_path):
        for filename in file_name_list:
            # 先保存到一起,如果mp4可以正常解析就直接使用,如果不行再移动到视频目录
            if filename.endswith("jpg") or filename.endswith("mp4"):
                file = []
                apath = os.path.join(maindir, filename)
                file.append(apath)
                file.append(filename)
                all_file_name.append(file)
    return all_file_name


# dst必须传全路径
def movefile(src,dst):
    # dst是全路径,如果已经存在则直接删除src,跳过此文件
    if os.path.exists(dst):
        os.remove(src)
        print(dst + "已经存在")
    else:
        shutil.move(src, dst)


if __name__ == '__main__':

    print("开始处理")
    if len(sys.argv) > 2:
        inpupath = sys.argv[1]
        outputpath = sys.argv[2]
        if inpupath is None or len(inpupath) <= 0:
            inpupath = r"E:\项目资料中心\相册整理\未分类"
        if outputpath is None or len(inpupath) <= 0:
            outputpath = r"E:\项目资料中心\相册整理\已分类"
    else:
        inpupath = r"E:\项目资料中心\相册整理\未分类"
        outputpath = r"E:\项目资料中心\相册整理\已分类"

    if not os.path.exists(outputpath):
        print('根目录不存在,创建')
        os.mkdir(outputpath)

    all_file_name = get_all_path(inpupath)

    for i in all_file_name:
        filePathName = i[0]
        filename = i[1]

        decompose = GetPhotoInfo(filePathName).get_location()
        #如果解析失败,则直接移动到文件夹
        if decompose is None:
            #如果无法解析并且是mp4格式的就直接移动到视频
            if filename.endswith("mp4"):
                movefile(filePathName, r"V:\\视频\\手机自动同步\\" + filename);
            else:
                #无法解析的先放到手机自动同步里
                movefile(filePathName, r"V:\\四海为家\\手机自动同步\\" + filename);
            continue
        add_sheng = outputpath + '\\' + decompose[0]
        add_shi = add_sheng + '\\' + decompose[1]
        add_qu = add_shi + '\\' + decompose[2]
        add_detail = add_qu + '\\' + decompose[3]
        if not os.path.exists(add_detail):
            os.makedirs(add_detail)
        movefile(filePathName, add_detail + '\\' + filename)
        time.sleep(0.1)

    print("处理完成");

代码直接打包成exe,不打包也不影响使用。

这里提一下,我本来准备放到nas中的宝塔中自动运行的,结果宝塔中装python太麻烦了,而且还需要很多的库。搞了一下午没弄成放弃了。

后来准备打包成可执行文件,结果,windows下打的包只能在windows下运行,诶。

所以就妥协了,直接在windows中运行,反正相册目录之前做过映射。

效果如下:

然后加到任务计划中。

选择每天一次
晚上执行不影响使用

其实运行很快的,什么时间都无所谓

启动程序
添加参数

一共需要两个参数

参数1是图片目录,选择自动同步的目录

参数2是输出目录,选择PhotoPrism映射的目录

配置完成

至此完成自动处理照片已经完成。

下面做PhotoPrism的自动同步

PhotoPrism中的同步需要点击开始才可以。

这个事本来我想着有现成的呢,结果并没有,不过百度上有现成的。参考一下。

打开nas中的控制台

/usr/bin/docker container ls

记录最前面的id

然后调用一下看看效果

/usr/bin/docker exec -i 你的id /photoprism/bin/photoprism index
可以看到日志

打开网页,也可以看到照片在增加,说明这个命令没问题。

然后安装User Scripts

直接搜索,然后安装即可。

然后发现安装失败,查了一下说这个网站挂了。

所以就只能另寻它法了,不过linux有自己的定时任务。

还是打开nas的控制台。

打开/etc/cron.d

vi root

增加一条

然后到对应位置,编写shell,填写刚刚的命令

到此,全自动同步照片加自动分类已经做好了。

从自动同步到服务器,到自动照片分类,加上自动同步到相册,实现全自动化处理照片。

由于昨天做的安卓同步挺好用的,今天也做一下苹果手机相册的自动同步。

苹果手机相册自动上传实现

首先安装icloudpd

直接app搜索即可。

点击安装。

只要修改这三个参数就可以了。

然后同样的,再加上一个任务计划,一切都是那么完美。


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。