前提准备
- 你需要
python
,以及下载python
的插件工具pip
; - 一个
码云
账号或者github
账号。
创建相册文件夹(远程)
在你的码云或者github
账号下新建一个仓库,名字任意,但是记住一定要是公开的仓库,否则博客中无法正常显示。并在改仓库中新建两个文件夹photo
和mini_photo
。
photo
文件夹中存放的是照片原图,而mini_photo
中存放的是照片的略缩图照片的命名方式请按照
yyyy-MM-dd_图片描述.png/jpg
的格式,方便管理以及程序对照片进行处理
对照片进行处理
在本地博客的上级目录中存放本地相册,在博客/source
文件夹中新建photos
目录
git clone 你的git仓库
这里我们采用python
脚本对照片进行处理,将脚本放在本地相册文件夹中
#coding: utf-8
from PIL import Image
import os
import sys
import json
from datetime import datetime
from ImageProcess import Graphics
# 定义压缩比,数值越大,压缩越小
SIZE_normal = 1.0
SIZE_small = 1.5
SIZE_more_small = 2.0
SIZE_more_small_small = 3.0
def make_directory(directory):
"""创建目录"""
os.makedirs(directory)
def directory_exists(directory):
"""判断目录是否存在"""
if os.path.exists(directory):
return True
else:
return False
def list_img_file(directory):
"""列出目录下所有文件,并筛选出图片文件列表返回"""
old_list = sorted(os.listdir(directory), reverse=True)
print(old_list)
new_list = []
for filename in old_list:
name, fileformat = filename.split(".")
if fileformat.lower() == "jpg" or fileformat.lower() == "png" or fileformat.lower() == "gif" or fileformat.lower() == "jpeg":
new_list.append(filename)
# print new_list
return new_list
def print_help():
print("""
This program helps compress many image files
you can choose which scale you want to compress your img(jpg/png/etc)
1) normal compress(4M to 1M around)
2) small compress(4M to 500K around)
3) smaller compress(4M to 300K around)
""")
def compress(choose, des_dir, src_dir, file_list):
"""压缩算法,img.thumbnail对图片进行压缩,
参数
-----------
choose: str
选择压缩的比例,有4个选项,越大压缩后的图片越小
"""
if choose == '1':
scale = SIZE_normal
if choose == '2':
scale = SIZE_small
if choose == '3':
scale = SIZE_more_small
if choose == '4':
scale = SIZE_more_small_small
for infile in file_list:
img = Image.open(src_dir+infile)
# size_of_file = os.path.getsize(infile)
w, h = img.size
img.thumbnail((int(w/scale), int(h/scale)))
img.save(des_dir + infile)
def compress_photo():
'''调用压缩图片的函数
'''
src_dir, des_dir = "photos/", "min_photos/"
if directory_exists(src_dir):
if not directory_exists(src_dir):
make_directory(src_dir)
# business logic
file_list_src = list_img_file(src_dir)
if directory_exists(des_dir):
if not directory_exists(des_dir):
make_directory(des_dir)
file_list_des = list_img_file(des_dir)
# print file_list
'''如果已经压缩了,就不再压缩'''
for i in range(len(file_list_des)):
if file_list_des[i] in file_list_src:
file_list_src.remove(file_list_des[i])
compress('4', des_dir, src_dir, file_list_src)
def handle_photo():
'''根据图片的文件名处理成需要的json格式的数据
-----------
最后将data.json文件存到博客的source/photos文件夹下
'''
src_dir, des_dir = "photos/", "min_photos/"
file_list = list_img_file(src_dir)
print(file_list)
list_info = []
for i in range(len(file_list)):
filename = file_list[i]
date_str, info = filename.split("_")
info, _ = info.split(".")
date = datetime.strptime(date_str, "%Y-%m-%d")
year_month = date_str[0:7]
if i == 0: # 处理第一个文件
new_dict = {
"date": year_month, "arr":{
'year': date.year,
'month': date.month,
'link': [filename],
'text': [info],
'type': ['image']
}
}
list_info.append(new_dict)
elif year_month != list_info[-1]['date']: # 不是最后的一个日期,就新建一个dict
new_dict = {
"date": year_month, "arr":{
'year': date.year,
'month': date.month,
'link': [filename],
'text': [info],
'type': ['image']
}
}
list_info.append(new_dict)
else: # 同一个日期
list_info[-1]['arr']['link'].append(filename)
list_info[-1]['arr']['text'].append(info)
list_info[-1]['arr']['type'].append('image')
list_info.reverse() # 翻转
tmp = bubbleYear(list_info)
bubble(tmp)
final_dict = {
"list": list_info}
with open("../hexoBlog/source/photos/data.json","w") as fp:
json.dump(final_dict, fp)
def cut_photo():
"""裁剪算法
----------
调用Graphics类中的裁剪算法,将src_dir目录下的文件进行裁剪(裁剪成正方形)
"""
src_dir = "photos/"
if directory_exists(src_dir):
if not directory_exists(src_dir):
make_directory(src_dir)
# business logic
file_list = list_img_file(src_dir)
# print file_list
if file_list:
print_help()
for infile in file_list:
img = Image.open(src_dir+infile)
img = img.convert('RGB')
Graphics(infile=src_dir+infile, outfile=src_dir + infile).cut_by_ratio()
else:
pass
else:
print("source directory not exist!")
def git_operation():
'''
git 命令行函数,将仓库提交
----------
需要安装git命令行工具,并且添加到环境变量中
'''
os.system('git add --all')
os.system('git commit -m "add photos"')
os.system('git push origin master')
def bubble(bubbleList):
listLength = len(bubbleList)
while listLength > 0:
for i in range(listLength - 1): # 这个循环负责设置冒泡排序进行的次数
# print(bubbleList[i])
for j in range(listLength-i-1): # j为列表下标
if(bubbleList[j].get('arr').get('year') == bubbleList[j+1].get('arr').get('year')):
if bubbleList[j].get('arr').get('month') < bubbleList[j+1].get('arr').get('month'):
bubbleList[j], bubbleList[j+1] = bubbleList[j+1], bubbleList[j]
return bubbleList
# for i in range(listLength - 1):
# if(bubbleList[i].get('arr').get('year') == bubbleList[i+1].get('arr').get('year')):
# if bubbleList[i].get('arr').get('month') > bubbleList[i+1].get('arr').get('month'):
# bubbleList[i] = bubbleList[i] + bubbleList[i+1]
# bubbleList[i+1] = bubbleList[i] - bubbleList[i+1]
# bubbleList[i] = bubbleList[i] - bubbleList[i+1]
# listLength -= 1
def bubbleYear(bubbleList):
listLength = len(bubbleList)
while listLength > 0:
for i in range(listLength - 1):
for j in range(listLength-i-1):
if bubbleList[j].get('arr').get('year') < bubbleList[j+1].get('arr').get('year'):
bubbleList[j], bubbleList[j+1] = bubbleList[j+1], bubbleList[j]
# print(bubbleList)
return bubbleList
if __name__ == "__main__":
cut_photo() # 裁剪图片,裁剪成正方形,去中间部分
compress_photo() # 压缩图片,并保存到mini_photos文件夹下
git_operation() # 提交到github仓库
handle_photo() # 将文件处理成json格式,存到博客仓库中
其中文件中的内容进行修改,将../hexoBlog/source/photos/data.json
改为你自己的本地博客地址
还需要一个额外的python
脚本ImageProcess.py
(上网搜了好久都没有,后面找到了源代码赶紧保存了下来)
# coding=utf-8
from PIL import Image
import shutil
import os
class Graphics:
''' 图片处理类
参数
-------
infile: 输入文件路径
outfile: 输出文件路径
'''
def __init__(self, infile, outfile):
self.infile = infile
self.outfile = outfile
def fixed_size(self, width, height):
"""按照固定尺寸处理图片"""
im = Image.open(self.infile)
out = im.resize((width, height),Image.ANTIALIAS)
out.save(self.outfile)
def resize_by_width(self, w_divide_h):
"""按照宽度进行所需比例缩放"""
im = Image.open(self.infile)
(x, y) = im.size
x_s = x
y_s = x/w_divide_h
out = im.resize((x_s, y_s), Image.ANTIALIAS)
out.save(self.outfile)
def resize_by_height(self, w_divide_h):
"""按照高度进行所需比例缩放"""
im = Image.open(self.infile)
(x, y) = im.size
x_s = y*w_divide_h
y_s = y
out = im.resize((x_s, y_s), Image.ANTIALIAS)
out.save(self.outfile)
def resize_by_size(self, size):
"""按照生成图片文件大小进行处理 (单位 KB)"""
size *= 1024
im = Image.open(self.infile)
size_tmp = os.path.getsize(self.infile)
q = 100
while size_tmp > size and q > 0:
print (q)
out = im.resize(im.size, Image.ANTIALIAS)
out.save(self.outfile, quality=q)
size_tmp = os.path.getsize(self.outfile)
q -= 5
if q == 100:
shutil.copy(self.infile, self.outfile)
def cut_by_ratio(self):
""" 按照图片长宽进行分割
------------
取中间的部分,裁剪成正方形
"""
im = Image.open(self.infile)
(x, y) = im.size
if x > y:
region = (int(x/2-y/2), 0, int(x/2+y/2), y)
#裁切图片
crop_img = im.crop(region)
#保存裁切后的图片
crop_img.save(self.outfile)
elif x < y:
region = (0, int(y/2-x/2), x, int(y/2+x/2))
#裁切图片
crop_img = im.crop(region)
#保存裁切后的图片
crop_img.save(self.outfile)
在运行之前还需要安装python
插件
pip install Pillow
将这两个文件都放在照片的文件夹里,运行脚本
python imageDeal.py
执行完后重新git
到远程仓库
如果提示缺少什么库,请自行使用
pip
安装即可
上面两个文件若是出错,可以到我的码云中下载
运行完成后会在你的博客目录/source/photos
中出现data.json
修改 Next 主题中的配置
增加相册 style
在 next 主题目录next/layout
下面增加 photo.swig 页面
{
% extends '_layout.swig' %}
{
% import '_macro/post-collapse.swig' as post_template %}
{
% import '_macro/sidebar.swig' as sidebar_template %}
{
% block title %}{
{
page.title }} | {
{
config.title }}{
% endblock %}
{
% block content %}
{
#################}
{
### Photo BLOCK ###}
{
#################}
<div class="post-block photo">
<div id="posts" class="posts-collapse">
</div>
</div>
{
#####################}
{
### END Photo BLOCK ###}
{
#####################}
{
% include '_partials/pagination.swig' %}
{
% endblock %}
{
% block sidebar %}
{
{
sidebar_template.render(false) }}
{
% endblock %}
生成相册页面
生成相册页面和生成分类和标签页面一样
hexo new page photos
修改博客/source/photos/index.md
<link rel="stylesheet" href="./ins.css">
<link rel="stylesheet" href="./photoswipe.css">
<link rel="stylesheet" href="./default-skin/default-skin.css">
<div class="photos-btn-wrap">
<a class="photos-btn active" href="javascript:void(0)">照片美如画</a>
</div>
<div class="instagram itemscope">
http://localhost:4000/mrxun" target="_blank" class="open-ins">图片正在加载中…
</div>
<script>
(function() {
var loadScript = function(path) {
var $script = document.createElement('script')
document.getElementsByTagName('body')[0].appendChild($script)
$script.setAttribute('src', path)
}
setTimeout(function() {
loadScript('./ins.js')
}, 0)
})()
</script>
将其中的网址http://localhost:4000/mrxun
换成你自己的域名
另外还需要三个css
,以及js
photoswipe.css
ins.css
default-skin/default-skin.css(新建文件夹后在放入css
文件)
ins.js
这些文件我也放在码云中
添加查看相册插件 photoswipe
在/theme/next/source/js
中添加photoswipe.min.js
和 photoswipe-ui-default.min.js
,这两个文件可以在github上下载
在 /theme/next/layout/_scripts/pages/post-details.swig
中插入以下两行(没有的话直接新建即可)
<script src="{
{ url_for(theme.js) }}/src/photoswipe.min.js?v={
{ theme.version }}"></script>
<script src="{
{ url_for(theme.js) }}/src/photoswipe-ui-default.min.js?v={
{ theme.version }}"></script>
在 /theme/next/layout/_layout.swig
的head
标签中添加下面几行
{
% if page.type === "photos" %}
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<div class="pswp__bg"></div>
<div class="pswp__scroll-wrap">
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
{
% endif %}
至此相册查看插件 photoswipe
已经配置完毕
总结
我们回顾以下整个流程
- 远程仓库
photos
- 本地文件夹,从远程仓库
git clone
- 博客中新建
photos
页面 - 执行
python
脚本处理照片 - 重新提交到
github
或码云
上 - 修改
博客/source/photos
中的index.md
,以及添加css
和js
文件 - 修改
主题/layout
文件夹中的一些文件 - 在
主题/source/js
文件夹中添加js
文件
主要参考的文章:https://lovexinforever.github.io/
十分感谢,并且其他添加相册的方法全部失效
原博的顺序以及文件已经非常不全面,我将过程重新梳理,所有需要的插件全部上传到码云,供大家使用