Python转换图片格式(png转换成webp)、批量上传至S3、生成json文件
json
适用于现代 C++ 的 JSON。
项目地址:https://gitcode.com/gh_mirrors/js/json
免费下载资源
·
在工作中遇到一个需求,需要将运营给出的png格式图片转换成webp格式,并将要求的图片上传至S3,同时生成一份json文件返回给产品。
其实一个脚本就可以搞定,但是后续每次转换上传,需要对路径等作出更改,考虑到为了让运营人员也可以轻松使用,在此使用Flask做一个页面,将所必须的信息填写好执行即可。
效果图:
index页面
成功跳转页面:
成功后进入S3查看确实已经上传,生成的json文件会生成在本地。
失败跳转页面:
废话少说,上代码。
1.首先编写一个简单的html页面,核心代码如下:
/*页面样式引入的bootstrap*/
<div class="row justify-content-center " style="height: 500px">
<div class="align-self-center">
<form action="http://localhost:8081/get/sum" target="_blank" method="POST">
<div class="form-row">
<div class="form-group col-sm-6">
<label for="exampleInput1">AWS_ID</label>
<input type="password" class="form-control" name="aws_id" id="exampleInput1"
aria-describedby="emailHelp"
placeholder="AWS_ACCESS_KEY_ID">
</div>
<div class="form-group col-sm-6">
<label for="exampleInput2">AWS_KEY</label>
<input type="password" class="form-control" name="aws_key" id="exampleInput2"
placeholder="AWS_SECRET_ACCESS_KEY">
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-12">
<label for="exampleInput3">输入您的 本地上传图片文件夹路径</label>
<input type="text" class="form-control" name="local_path" id="exampleInput3"
placeholder="eg:/Users/xm20201102/Documents/bigemoji_0519_png">
</div>
<div class="form-group col-sm-12">
/*输入这个是工作需求中为了生成最后的json文件*/
<label for="exampleInput4">输入您下载的 emojiUnicode的csv文件路径</label>
<input type="text" class="form-control" id="exampleInput4" name="csv_path"
placeholder="eg:/Users/xm20201102/Desktop/big_emoji_list_1.csv">
</div>
</div>
<div class="form-check" align="center">
<input type="checkbox" class="form-check-input" id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">记住我的选择</label>
</div>
<div align="center">
<button type="submit" class="btn btn-primary">Go!</button>
</div>
</form>
</div>
</div>
2.编写后台处理逻辑:
首先导入我们需要的包:
import requests
from flask import Flask, request, jsonify, redirect
import boto3
import time
import os
from PIL import Image
from flask.helpers import url_for
from flask.templating import render_template
定义一些全局变量:
BUCKET_NAME = 'upload-bucket' #S3上已经创建好的桶名称
REGION_NAME = 'us-east-1' #S3账户时区
#以下四个路径是S3存储桶中图片存放的路径,因为不同图片存放路径不同,一共有四个路径。
PHOTO_DIRNAME_3d_WEBP = '3d/webp/'
PHOTO_DIRNAME_3d_PNG = '3d/png/'
PHOTO_DIRNAME_2d_WEBP = '2d/webp/'
PHOTO_DIRNAME_2d_PNG = '2d/png/'
S3_PATH = '' #生成json文件时用到,根据自己需求是否保留,https://cdn域名/存放路径
AWS_ACCESS_KEY_ID = '' #AWS账户Access key ID,从前端页面接收,也可写死,写死后去除前端输入框
AWS_SECRET_ACCESS_KEY = '' #AWS账户Secret access key,从前端页面接收,也可写死,写死后去除前端输入框
PHOTO_FOLDER = '' #本地图片文件夹存放路径,从前端页面接收
BIG_EMOJI_UNICODE_LIST_CSV = '' #生成json文件时用到,根据自己需求是否保留,从前端页面接收,本次需求是从给出的csv文件中提出每行的emojiUnicode
EMOJI_UNICODE = 'None' #生成json文件时用到,根据自己需求是否保留,会在后续赋值
LOCAL_PATH = '' #生成json文件时用到,根据自己需求是否保留,会在后续赋值
app = Flask(__name__) #使用flask必须加这个
#初始化生成一个app对象,这个对象就是Flask的当前实例对象,后面的各个方法调用都是这个实例
#Flask会进行一系列自己的初始化,比如web API路径初始化,web资源加载,日志模块创建等。然后返回这个创建好的对象给你
接收前端输入数据并处理:
@app.route("/get/sum", methods=["GET", "POST"])
def get_sum():
global AWS_ACCESS_KEY_ID
global AWS_SECRET_ACCESS_KEY
global PHOTO_FOLDER
global BIG_EMOJI_UNICODE_LIST_CSV
global LOCAL_PATH
#给已定义的全局变量赋值
AWS_ACCESS_KEY_ID = request.form['aws_id']
AWS_SECRET_ACCESS_KEY = request.form['aws_key']
PHOTO_FOLDER = request.form['local_path']
BIG_EMOJI_UNICODE_LIST_CSV = request.form['csv_path']
LOCAL_PATH = PHOTO_FOLDER[:-1]
#若输入的信息有空,重定向到错误页面
if AWS_ACCESS_KEY_ID == '' or AWS_SECRET_ACCESS_KEY == '' or PHOTO_FOLDER == '' or BIG_EMOJI_UNICODE_LIST_CSV == '':
return redirect(url_for('get_error'))
#开始逻辑处理
start() #选择png格式图片并转换成webp格式
upload_photo_512_and_150_webp() # 批量上传512和150大小的webp图片
upload_photo_512_png() # 批量上传512大小的png图片
print_json() #输出json文件
return redirect(url_for('get_response', path=PHOTO_FOLDER, photo='static/home3_02_05.png'))
#调用成功页面
@app.route("/get_response", methods=["GET", "POST"])
def get_response():
return render_template("success.html",
path=request.args.get('path'), photo=request.args.get('photo'))
#调用失败页面
@app.route("/get_error", methods=["GET", "POST"])
def get_error():
return render_template("error.html")
# 去除目录中非png格式的,只选择png格式进行转换,开始转换。若没有则不转换
def start():
filePath = PHOTO_FOLDER
res = os.listdir(filePath)
for path in res:
#mac本读取文件夹内容时,会有默认存在的.DS_Store文件,和文件排序等有关,不转换它,也可以在终端输入命令让其不生成
if path != '.DS_Store' and path.endswith('.png'):
to_webp(filePath + path)
# 转换格式png to webp
def to_webp(path):
im = Image.open(path)
save_dir = path.replace('0512', '0512_webp')
save_dir = save_dir.replace('.png', '.webp')
im.save(save_dir, "WEBP")
# 批量上传*.webp
def upload_photo_512_and_150_webp():
os.chdir(PHOTO_FOLDER)
logo_list = os.listdir(PHOTO_FOLDER)
for logo in logo_list:
if not os.path.isfile(os.path.abspath(logo)):
logo_list.remove(logo)
if logo.endswith('.webp') and logo != '.DS_Store':
upload_photo(photo_name=logo)
# 批量上传512*512.png
def upload_photo_512_png():
os.chdir(PHOTO_FOLDER)
logo_list = os.listdir(PHOTO_FOLDER)
for logo in logo_list:
if not os.path.isfile(os.path.abspath(logo)):
logo_list.remove(logo)
# 只检测后缀为_512.png的上传,_150.png的不上传
if logo.endswith('_512.png') and logo != '.DS_Store':
upload_photo(photo_name=logo)
# S3上传单个文件
def upload_photo(bucket_name=BUCKET_NAME, photo_name=None):
upload_photo_s3 = init_s3_photo(REGION_NAME, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
if '3d' in photo_name:
if photo_name.endswith('.webp'):
with open(os.path.join(PHOTO_FOLDER, photo_name), 'rb') as f:
photo_stream = f.read()
key_name = PHOTO_DIRNAME_3d_WEBP + photo_name
else:
with open(os.path.join(PHOTO_FOLDER, photo_name), 'rb') as f:
photo_stream = f.read()
key_name = PHOTO_DIRNAME_3d_PNG + photo_name
else:
if photo_name.endswith('.webp'):
with open(os.path.join(PHOTO_FOLDER, photo_name), 'rb') as f:
photo_stream = f.read()
key_name = PHOTO_DIRNAME_2d_WEBP + photo_name
else:
with open(os.path.join(PHOTO_FOLDER, photo_name), 'rb') as f:
photo_stream = f.read()
key_name = PHOTO_DIRNAME_2d_PNG + photo_name
try:
# upload to s3,key_name指定S3上的路径
upload_photo_s3.Bucket(bucket_name).upload_file(Filename=photo_name, Key=key_name,
ExtraArgs={'ACL': 'public-read'})
#注意上传时必须加这个参数ExtraArgs={'ACL': 'public-read'},否则会报没有权限错误
print("{} upload done".format(photo_name))
except Exception as e:
print("upload {} error:{}".format(photo_name, e))
# 生成json并写到文件里
def print_json():
global EMOJI_UNICODE
data = []
count = 0
for root, dirs, files in os.walk(LOCAL_PATH):
for name in files:
if name.endswith('.webp'):
s3_path_512 = os.path.join(root, name).replace(LOCAL_PATH,
S3_PATH)
if s3_path_512.endswith('_150.webp'):
webp_150 = s3_path_512
else:
webp_150 = s3_path_512.replace("_512.webp", "_150.webp")
temp_path = webp_150
webp_512 = temp_path.replace("_150.webp", "_512.webp")
id = name[:-9]
# 下载的csv路径
with open(BIG_EMOJI_UNICODE_LIST_CSV) as f:
for line in f:
if id == line.split(",")[0]:
EMOJI_UNICODE = line.split(",")[1]
break
if '2d' in id:
webp_150 = webp_150.replace("3d", "2d")
webp_512 = webp_512.replace("3d", "2d")
nameJson = {
"emoji_unicode": EMOJI_UNICODE,
"big_emoji_id": id,
"big_emoji_preview": webp_150,
"big_emoji_url_webp": webp_512,
"big_emoji_url_png": webp_512.replace("webp", "png")
}
if nameJson not in data:
data.append(nameJson)
count += 1
sort_data = sorted(data, key=lambda e: e.__getitem__('big_emoji_id'))
JSON_data = str(sort_data).replace("'", "\"").replace(r"\n", "")
now_time = int((time.time()))
time_local = time.localtime(now_time)
dt = time.strftime("%Y-%m-%d_%H:%M:%S", time_local)
# 输出到当前图片目录json文件中
with open(dt + "_upload_bigEmoji.json", 'w') as f:
f.write(JSON_data)
# 连接S3
def init_s3_photo(region_name, aws_access_key_id,
aws_secret_access_key):
s3 = boto3.resource('s3', region_name=region_name, aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key)
return s3
#主函数入口,可以设置端口号
if __name__ == "__main__":
app.config["JSON_AS_ASCII"] = False
app.run(host="127.0.0.1", port=8081)
到这里就基本完成了,还有一个成功或失败跳转的html页面没有放上来,随便做一个就行了,我们主要目的是实现需求功能,并可以持续使用。如果有问题或者指导我的小伙伴们可以评论我,看到都会回复。
GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e
4 个月前
8c391e04
6 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)