虽然我部署了Lsky 来管理图床,但我的小服务器硬盘只有50G空间,图片还是得处理下再存储比较好,顺便还用python打包了一个转换压缩图片为webp的exe工具
下载文件:百度网盘链接
提取码:abcd
需求与解决方案
- 图片格式转换和压缩存储
- 尽可能降低响应时间
· - 使用Redis当作消息队列,用作脚本和Lsky之间的通信
- 使用Python Pillow库编写脚本处理转换压缩图片
思路
PS:下面代码仅作示例,非可直接执行代码。
在 Laravel 中配置 Redis 队列:
Lsky开源版本composer.json没有redis需要自己安装 Redis 驱动,配置 .env,
composer require predis/predis
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
在任务中发送消息:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;
class ProcessPythonTask implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $data;
public function __construct($data)
{
$this->data = $data;
}
public function handle()
{
Redis::rpush('python_tasks', json_encode($this->data));
}
}
在 Python 中消费消息:
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
while True:
task = r.blpop('python_tasks', timeout=0)
if task:
data = json.loads(task[1])
print("Received task:", data)
在 Laravel 中分发任务:
// 每当上传成功一个图片就把这个图片信息添加到redis
ProcessPythonTask::dispatch(['message' => 'Hello from Laravel!']);
Python与Mysql通信:
import pymysql
# 创建数据库连接
conn = pymysql.connect(
host='localhost', # 主机地址
user='root', # 用户名
password='password', # 密码
database='test_db' # 数据库名
)
# 创建游标对象
cursor = conn.cursor()
# 执行 SQL 查询
cursor.execute("SELECT * FROM your_table")
# 获取查询结果
result = cursor.fetchall()
for row in result:
print(row)
# 关闭连接
cursor.close()
conn.close()
Python实现图片转换:
# 省略代码.....
failed_images = [] # 用于记录转换失败的图片
compression_type = ["无损","自动","有损"]
output_format = "WEBP"
def process_images(image,quality=80):
try:
with Image.open(image['path']) as img:
if compression_type == "无损":
img.save(image['path'], output_format.upper(), lossless=True)
elif compression_type == "自动":
img.save(image['path'], output_format.upper())
else:
img.save(image['path'], output_format.upper(), quality=quality)
except Exception as e:
failed_images.append(image)
logging.error(f"处理图片 {image['origin_name']} 时发生错误: {e}", exc_info=True)
def record_db(insert_data,update_data):
try:
conn.start_transaction()
# 记录转换压缩失败图片到数据库,这个表要自己建
insert_query = "INSERT INTO your_table (name, age) VALUES (%s, %s)"
cursor.executemany(insert_query, insert_data)
# 更改转换成功的图片数据
update_query = "UPDATE your_table SET age = %s WHERE name = %s"
cursor.executemany(update_query, update_data)
conn.commit() # 提交事务
except Exception as e:
logging.error(f"记录转换失败图片 {image['origin_name']} 时发生错误: {e}", exc_info=True)
conn.rollback() # 回滚事务
os.remove(update_data['new_path'])
finally:
# 关闭连接
cursor.close()
conn.close()
# 删除原图
os.remove(update_data['old_path'])
# 省略代码...
评论区