Python图片处理:基于Gradio构建启动后在浏览器打开交互界面,支持上传图片、自由拖拽4个顶点实现任意角度拉伸压缩、并添加文字
2026/7/3 5:41:22 网站建设 项目流程

完整代码(保存为 image_warp.py 并运行)

```python

import gradio as gr

import cv2

import numpy as np

from PIL import Image, ImageDraw, ImageFont

# 核心处理函数

def warp_image(image,

tl_x, tl_y, # 左上角偏移

tr_x, tr_y, # 右上角偏移

br_x, br_y, # 右下角偏移

bl_x, bl_y, # 左下角偏移

text, # 要添加的文字

text_x, text_y, # 文字位置

font_size,

font_color,

bg_color):

h, w = image.shape[:2]

# 原始四个角点

pts_src = np.float32([[0, 0], [w, 0], [w, h], [0, h]])

# 目标四个角点(用户通过滑块控制偏移)

pts_dst = np.float32([

[0 + tl_x, 0 + tl_y],

[w + tr_x, 0 + tr_y],

[w + br_x, h + br_y],

[0 + bl_x, h + bl_y]

])

# 计算透视变换矩阵

M = cv2.getPerspectiveTransform(pts_src, pts_dst)

# 计算变换后完整图像的边界框,避免裁剪

all_pts = pts_dst.copy()

min_x = min(all_pts[:, 0])

max_x = max(all_pts[:, 0])

min_y = min(all_pts[:, 1])

max_y = max(all_pts[:, 1])

# 保证最小尺寸,防止矩阵报错

out_w = int(max_x - min_x) + 20

out_h = int(max_y - min_y) + 20

if out_w < 10 or out_h < 10:

out_w, out_h = w, h

# 平移矩阵,让整个变形后的画面显示在画布中央

T = np.array([[1, 0, -min_x + 10], [0, 1, -min_y + 10], [0, 0, 1]], dtype=np.float32)

M = T @ M

# 执行透视变形

warped = cv2.warpPerspective(image, M, (out_w, out_h))

# ----- 添加文字(PIL支持中文,若系统无中文字体则回退默认)-----

pil_img = Image.fromarray(cv2.cvtColor(warped, cv2.COLOR_BGR2RGB))

draw = ImageDraw.Draw(pil_img)

try:

# 尝试加载系统字体(Windows用simhei,Mac用PingFang,Linux用arial)

font = ImageFont.truetype("simhei.ttf", int(font_size))

except:

try:

font = ImageFont.truetype("PingFang.ttc", int(font_size))

except:

font = ImageFont.load_default()

# 解析颜色 (#RRGGBB格式)

def hex_to_rgb(hex_str):

hex_str = hex_str.lstrip('#')

return tuple(int(hex_str[i:i+2], 16) for i in (0, 2, 4))

f_color = hex_to_rgb(font_color)

b_color = hex_to_rgb(bg_color) if bg_color else None

# 若设置了背景色,先绘制文字背景框

if b_color:

bbox = draw.textbbox((text_x, text_y), text, font=font)

draw.rectangle(bbox, fill=b_color)

# 绘制文字

draw.text((text_x, text_y), text, font=font, fill=f_color)

# 转回OpenCV格式返回

result = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)

return result

# ----- 构建 Gradio 界面 -----

with gr.Blocks(title="图片任意角度拉伸压缩+添加文字", theme=gr.themes.Soft()) as demo:

gr.Markdown("## 上传图片,拖拽滑块控制四个角,实现任意角度拉伸/压缩,并添加文字")

with gr.Row():

with gr.Column(scale=1):

input_img = gr.Image(label=" 上传图片", type="numpy", height=300)

gr.Markdown("### 顶点偏移控制(正负值均可)")

with gr.Row():

tl_x = gr.Slider(-300, 300, value=0, label="左上 X")

tl_y = gr.Slider(-300, 300, value=0, label="左上 Y")

with gr.Row():

tr_x = gr.Slider(-300, 300, value=0, label="右上 X")

tr_y = gr.Slider(-300, 300, value=0, label="右上 Y")

with gr.Row():

br_x = gr.Slider(-300, 300, value=0, label="右下 X")

br_y = gr.Slider(-300, 300, value=0, label="右下 Y")

with gr.Row():

bl_x = gr.Slider(-300, 300, value=0, label="左下 X")

bl_y = gr.Slider(-300, 300, value=0, label="左下 Y")

gr.Markdown("### 文字设置")

text_input = gr.Textbox(value="你好,世界!", label="文字内容")

with gr.Row():

text_x = gr.Slider(0, 800, value=50, label="文字 X 位置")

text_y = gr.Slider(0, 600, value=50, label="文字 Y 位置")

with gr.Row():

font_size = gr.Slider(10, 100, value=40, label="字号")

font_color = gr.Textbox(value="#FF0000", label="字体颜色 (如 #FF0000)")

bg_color = gr.Textbox(value="#000000", label="背景颜色 (留空则透明)")

btn = gr.Button("🚀 执行变形并添加文字", variant="primary")

with gr.Column(scale=1):

output_img = gr.Image(label="📥 处理结果", type="numpy", height=500)

# 绑定按钮事件

btn.click(

fn=warp_image,

inputs=[input_img, tl_x, tl_y, tr_x, tr_y, br_x, br_y, bl_x, bl_y,

text_input, text_x, text_y, font_size, font_color, bg_color],

outputs=output_img

)

# 示例提示

gr.Markdown("""

### 💡 使用技巧

- 拖动四个角的 **X/Y 偏移滑块**,画面会像纸张一样被拉伸或压缩,实现透视变形。

- 支持 **负值**(向内收缩)和 **正值**(向外扩张)。

- 文字颜色和背景色请使用 **#RRGGBB** 格式(例如 `#FF0000` 为红色)。

""")

if __name__ == "__main__":

demo.launch()

```

---

运行方法

1. 安装依赖(打开终端或命令提示符):

```bash

pip install gradio opencv-python pillow numpy

```

2. 运行程序:

```bash

python image_warp.py

```

3. 使用:

· 终端会显示本地访问地址(通常是 http://127.0.0.1:7860),用浏览器打开。

· 上传图片 → 拖动8个滑块控制4个顶点 → 填写文字 → 点击按钮,即可实时看到变形+文字效果。

功能说明

· 任意角度拉伸/压缩:通过独立控制四个顶点的偏移量,可实现透视、扭曲、缩放等所有变形效果。

· 添加文字:支持中英文,可调字号、颜色,并可设置文字背景色(或透明)。

· 画面自适应:变形后画面自动扩展画布,不会裁剪超出部分。

如果调整滑块的取值范围(当前为 -300 ~ 300),修改代码中 Slider 的 minimum 和 maximum 参数即可(如改为 -500 ~ 500)。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询