Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f720f02d2 | |||
| a99cb57a2f | |||
| 6db10c0c83 | |||
| 8bdd18bdcf | |||
| 1bf6d6448c | |||
| 7bde3ce551 | |||
| 7ad0538039 | |||
| 5aa802e960 | |||
| 7544e47ed3 |
35
app.py
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
图片编辑器 - Image Editor v1.1.0
|
图片编辑器 - Image Editor v1.2.7
|
||||||
前端图片处理工具:合并、分割、挖孔填充、圆形切图、文字图片等
|
前端图片处理工具:合并、分割、挖孔填充、圆形切图、文字图片等
|
||||||
新增:撤销/恢复功能、合并图片顺序调整、尺寸自定义
|
v1.2.7: 修复合并图片紧密拼接问题
|
||||||
|
|
||||||
端口: 19018
|
端口: 19018
|
||||||
"""
|
"""
|
||||||
@@ -10,30 +10,25 @@ from flask import Flask, render_template, jsonify, request, send_file
|
|||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import base64
|
import base64
|
||||||
import io
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
app = Flask(__name__, static_folder='static', static_url_path='/static')
|
app = Flask(__name__, static_folder='static', static_url_path='/static')
|
||||||
CORS(app)
|
CORS(app)
|
||||||
|
|
||||||
# 输出目录
|
|
||||||
OUTPUT_DIR = Path(__file__).parent / 'outputs'
|
OUTPUT_DIR = Path(__file__).parent / 'outputs'
|
||||||
OUTPUT_DIR.mkdir(exist_ok=True)
|
OUTPUT_DIR.mkdir(exist_ok=True)
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
"""主页"""
|
|
||||||
return render_template('index.html')
|
return render_template('index.html')
|
||||||
|
|
||||||
@app.route('/api/health')
|
@app.route('/api/health')
|
||||||
def health():
|
def health():
|
||||||
"""健康检查"""
|
return jsonify({'status': 'ok', 'version': '1.2.7', 'time': datetime.now().isoformat()})
|
||||||
return jsonify({'status': 'ok', 'version': '1.1.0', 'time': datetime.now().isoformat()})
|
|
||||||
|
|
||||||
@app.route('/api/save', methods=['POST'])
|
@app.route('/api/save', methods=['POST'])
|
||||||
def save_image():
|
def save_image():
|
||||||
"""保存图片"""
|
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
image_data = data.get('image', '')
|
image_data = data.get('image', '')
|
||||||
filename = data.get('filename', f'image_{uuid.uuid4().hex[:8]}.png')
|
filename = data.get('filename', f'image_{uuid.uuid4().hex[:8]}.png')
|
||||||
@@ -41,33 +36,23 @@ def save_image():
|
|||||||
if not image_data:
|
if not image_data:
|
||||||
return jsonify({'error': '无图片数据'}), 400
|
return jsonify({'error': '无图片数据'}), 400
|
||||||
|
|
||||||
# 解析 base64
|
|
||||||
if image_data.startswith('data:image'):
|
if image_data.startswith('data:image'):
|
||||||
image_data = image_data.split(',', 1)[1]
|
image_data = image_data.split(',', 1)[1]
|
||||||
|
|
||||||
# 保存
|
|
||||||
image_bytes = base64.b64decode(image_data)
|
|
||||||
filepath = OUTPUT_DIR / filename
|
filepath = OUTPUT_DIR / filename
|
||||||
filepath.write_bytes(image_bytes)
|
filepath.write_bytes(base64.b64decode(image_data))
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({'success': True, 'filename': filename})
|
||||||
'success': True,
|
|
||||||
'filename': filename,
|
|
||||||
'path': str(filepath)
|
|
||||||
})
|
|
||||||
|
|
||||||
@app.route('/api/download/<filename>')
|
@app.route('/api/download/<filename>')
|
||||||
def download_image(filename):
|
def download_image(filename):
|
||||||
"""下载图片"""
|
|
||||||
filepath = OUTPUT_DIR / filename
|
filepath = OUTPUT_DIR / filename
|
||||||
if not filepath.exists():
|
if not filepath.exists():
|
||||||
return jsonify({'error': '文件不存在'}), 404
|
return jsonify({'error': '文件不存在'}), 404
|
||||||
|
|
||||||
return send_file(filepath, as_attachment=True)
|
return send_file(filepath, as_attachment=True)
|
||||||
|
|
||||||
@app.route('/api/list')
|
@app.route('/api/list')
|
||||||
def list_images():
|
def list_images():
|
||||||
"""列出已保存的图片"""
|
|
||||||
images = []
|
images = []
|
||||||
for f in OUTPUT_DIR.glob('*.png'):
|
for f in OUTPUT_DIR.glob('*.png'):
|
||||||
images.append({
|
images.append({
|
||||||
@@ -75,19 +60,13 @@ def list_images():
|
|||||||
'size': f.stat().st_size,
|
'size': f.stat().st_size,
|
||||||
'time': datetime.fromtimestamp(f.stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S')
|
'time': datetime.fromtimestamp(f.stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
})
|
})
|
||||||
|
|
||||||
return jsonify({'images': sorted(images, key=lambda x: x['time'], reverse=True)})
|
return jsonify({'images': sorted(images, key=lambda x: x['time'], reverse=True)})
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
print("图片编辑器 - Image Editor v1.1.0")
|
print("图片编辑器 - Image Editor v1.2.7")
|
||||||
print("=" * 50)
|
|
||||||
print("新增功能:")
|
|
||||||
print(" - 撤销/恢复操作")
|
|
||||||
print(" - 合并图片顺序拖拽调整")
|
|
||||||
print(" - 合并图片尺寸自定义")
|
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
|
print("修复合并图片紧密拼接问题")
|
||||||
print(f"访问地址: http://localhost:19018")
|
print(f"访问地址: http://localhost:19018")
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
|
|
||||||
app.run(host='0.0.0.0', port=19018, debug=True)
|
app.run(host='0.0.0.0', port=19018, debug=True)
|
||||||
BIN
outputs/edited_1776739697628.png
Normal file
|
After Width: | Height: | Size: 684 KiB |
BIN
outputs/edited_1776739802945.png
Normal file
|
After Width: | Height: | Size: 796 KiB |
BIN
outputs/edited_1776739910151.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
outputs/edited_1776739994702.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
outputs/edited_1776755761871.png
Normal file
|
After Width: | Height: | Size: 763 KiB |
BIN
outputs/edited_1776761087118.png
Normal file
|
After Width: | Height: | Size: 763 KiB |
BIN
outputs/edited_1776778260696.png
Normal file
|
After Width: | Height: | Size: 768 KiB |
BIN
outputs/edited_1776778342793.png
Normal file
|
After Width: | Height: | Size: 767 KiB |
BIN
outputs/edited_1776778549740.png
Normal file
|
After Width: | Height: | Size: 796 KiB |