Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f720f02d2 |
10
app.py
10
app.py
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
图片编辑器 - Image Editor v1.2.6
|
||||
图片编辑器 - Image Editor v1.2.7
|
||||
前端图片处理工具:合并、分割、挖孔填充、圆形切图、文字图片等
|
||||
v1.2.6: 操作后显示预览效果,保留原始图片
|
||||
v1.2.7: 修复合并图片紧密拼接问题
|
||||
|
||||
端口: 19018
|
||||
"""
|
||||
@@ -25,7 +25,7 @@ def index():
|
||||
|
||||
@app.route('/api/health')
|
||||
def health():
|
||||
return jsonify({'status': 'ok', 'version': '1.2.6', 'time': datetime.now().isoformat()})
|
||||
return jsonify({'status': 'ok', 'version': '1.2.7', 'time': datetime.now().isoformat()})
|
||||
|
||||
@app.route('/api/save', methods=['POST'])
|
||||
def save_image():
|
||||
@@ -64,9 +64,9 @@ def list_images():
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("=" * 50)
|
||||
print("图片编辑器 - Image Editor v1.2.6")
|
||||
print("图片编辑器 - Image Editor v1.2.7")
|
||||
print("=" * 50)
|
||||
print("操作后显示预览效果,保留原始图片")
|
||||
print("修复合并图片紧密拼接问题")
|
||||
print(f"访问地址: http://localhost:19018")
|
||||
print("=" * 50)
|
||||
app.run(host='0.0.0.0', port=19018, debug=True)
|
||||
BIN
outputs/edited_1776778260696.png
Normal file
BIN
outputs/edited_1776778260696.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 768 KiB |
BIN
outputs/edited_1776778342793.png
Normal file
BIN
outputs/edited_1776778342793.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 767 KiB |
BIN
outputs/edited_1776778549740.png
Normal file
BIN
outputs/edited_1776778549740.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 796 KiB |
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>图片编辑器 - Image Editor v1.2.6</title>
|
||||
<title>图片编辑器 - Image Editor v1.2.7</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
|
||||
<style>
|
||||
@@ -1081,20 +1081,76 @@
|
||||
return { width: size.width || item.width, height: size.height || item.height };
|
||||
};
|
||||
|
||||
// 计算画布尺寸
|
||||
let canvasWidth = 0, canvasHeight = 0;
|
||||
|
||||
if (uniformSize) {
|
||||
// 统一尺寸:使用固定单元格大小
|
||||
let maxWidth = 0, maxHeight = 0;
|
||||
state.mergeImageOrder.forEach(item => {
|
||||
const size = getActualSize(item);
|
||||
maxWidth = Math.max(maxWidth, size.width);
|
||||
maxHeight = Math.max(maxHeight, size.height);
|
||||
});
|
||||
canvasWidth = cols * maxWidth + (cols - 1) * gap;
|
||||
canvasHeight = rows * maxHeight + (rows - 1) * gap;
|
||||
} else {
|
||||
// 不统一尺寸:紧密拼接,累加实际尺寸
|
||||
if (direction === 'horizontal') {
|
||||
// 横向:累加宽度,取最大高度
|
||||
state.mergeImageOrder.forEach(item => {
|
||||
const size = getActualSize(item);
|
||||
canvasWidth += size.width + gap;
|
||||
canvasHeight = Math.max(canvasHeight, size.height);
|
||||
});
|
||||
canvasWidth -= gap; // 去掉最后一个多余的gap
|
||||
} else if (direction === 'vertical') {
|
||||
// 纵向:累加高度,取最大宽度
|
||||
state.mergeImageOrder.forEach(item => {
|
||||
const size = getActualSize(item);
|
||||
canvasHeight += size.height + gap;
|
||||
canvasWidth = Math.max(canvasWidth, size.width);
|
||||
});
|
||||
canvasHeight -= gap;
|
||||
} else {
|
||||
// 网格:每行累加宽度,累加行高度
|
||||
for (let r = 0; r < rows; r++) {
|
||||
let rowWidth = 0, rowHeight = 0;
|
||||
for (let c = 0; c < cols; c++) {
|
||||
const idx = r * cols + c;
|
||||
if (idx < state.mergeImageOrder.length) {
|
||||
const size = getActualSize(state.mergeImageOrder[idx]);
|
||||
rowWidth += size.width + gap;
|
||||
rowHeight = Math.max(rowHeight, size.height);
|
||||
}
|
||||
}
|
||||
rowWidth -= gap;
|
||||
canvasWidth = Math.max(canvasWidth, rowWidth);
|
||||
canvasHeight += rowHeight + gap;
|
||||
}
|
||||
canvasHeight -= gap;
|
||||
}
|
||||
}
|
||||
|
||||
canvas.width = cols * maxWidth + (cols - 1) * gap;
|
||||
canvas.height = rows * maxHeight + (rows - 1) * gap;
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
|
||||
// 绘制合并结果到画布(预览)
|
||||
ctx.fillStyle = bgColor;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// 绘制图片
|
||||
let currentX = 0, currentY = 0;
|
||||
|
||||
if (uniformSize) {
|
||||
// 统一尺寸:固定单元格,居中绘制
|
||||
let maxWidth = 0, maxHeight = 0;
|
||||
state.mergeImageOrder.forEach(item => {
|
||||
const size = getActualSize(item);
|
||||
maxWidth = Math.max(maxWidth, size.width);
|
||||
maxHeight = Math.max(maxHeight, size.height);
|
||||
});
|
||||
|
||||
state.mergeImageOrder.forEach((orderItem, index) => {
|
||||
if (index >= cols * rows) return;
|
||||
const col = index % cols;
|
||||
@@ -1110,6 +1166,33 @@
|
||||
ctx.drawImage(originalImg.img, x + offsetX, y + offsetY, size.width, size.height);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 不统一尺寸:紧密拼接,无居中偏移
|
||||
state.mergeImageOrder.forEach((orderItem, index) => {
|
||||
const size = getActualSize(orderItem);
|
||||
const originalImg = state.images.find(img => img.name === orderItem.name);
|
||||
|
||||
if (!originalImg) return;
|
||||
|
||||
if (direction === 'horizontal') {
|
||||
ctx.drawImage(originalImg.img, currentX, 0, size.width, size.height);
|
||||
currentX += size.width + gap;
|
||||
} else if (direction === 'vertical') {
|
||||
ctx.drawImage(originalImg.img, 0, currentY, size.width, size.height);
|
||||
currentY += size.height + gap;
|
||||
} else {
|
||||
// 网格模式
|
||||
const col = index % cols;
|
||||
const row = Math.floor(index / cols);
|
||||
if (col === 0) currentX = 0;
|
||||
ctx.drawImage(originalImg.img, currentX, currentY, size.width, size.height);
|
||||
currentX += size.width + gap;
|
||||
if (col === cols - 1 || index === state.mergeImageOrder.length - 1) {
|
||||
currentY += size.height + gap;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 显示预览效果(不清除原始图片)
|
||||
const mergedData = canvas.toDataURL('image/png');
|
||||
|
||||
Reference in New Issue
Block a user