You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PIL生成ASCII艺术脚本报错:'str' object has no attribute 'size'

解决AttributeError: 'str' object has no attribute 'size'问题

问题根源

  1. 文件名不匹配:你用cv2.imwrite(f"frame{count}.jpg", image)保存的是frame{count}.jpg,但调用ascii函数时传入的是f"image{count}.jpg",导致PIL找不到文件,image变量保持为字符串路径,进而传给resize函数引发错误。
  2. 错误处理不完整:ascii函数中,若PIL.Image.open失败,没有终止后续逻辑,依然将原始字符串传入resize函数,而字符串没有size属性。
  3. resize参数类型错误:计算new_height得到的是浮点数,但image.resize要求尺寸为整数,会引发隐性错误。

修复方案

1. 修正文件名匹配

修改调用代码中的文件名,确保和保存的文件一致:

with open(f"ascii{count}.txt", "w") as f:
    f.write(ascii(f"frame{count}.jpg"))  # 改为frame开头,和保存的文件名对应

2. 完善错误处理逻辑

在ascii函数中,打开失败时直接返回空字符串,避免后续错误执行:

def ascii(image_path):
    try:
        image = PIL.Image.open(image_path)
    except Exception as e:
        print(f"{image_path} 无法打开,错误信息: {e}")
        return ""  # 打开失败时返回空,终止后续流程
    image = resize(image)
    greyscale_image = to_greyscale(image)
    ascii_str = pixel_to_ascii(greyscale_image)
    img_width = greyscale_image.width
    ascii_str_len = len(ascii_str)
    ascii_img=""
    for i in range(0, ascii_str_len, img_width):
        ascii_img += ascii_str[i:i+img_width] + "\n"
    return ascii_img

(注:将参数名从image改为image_path,更清晰区分路径字符串和Image对象)

3. 修正resize函数的尺寸类型

将计算出的new_height转为整数,符合resize方法的参数要求:

def resize(image, new_width = 100):
    old_width, old_height = image.size
    new_height = int(new_width * old_height / old_width)  # 转为整数
    return image.resize((new_width, new_height))

完整修正后的get_ascii.py代码

import PIL.Image

ASCII_CHARS = ["@", "#", "$", "%", "?", "*", "+", ";", ":", ",", "."]

def pixel_to_ascii(image):
    pixels = image.getdata()
    ascii_str = ""
    for pixel in pixels:
        ascii_str += ASCII_CHARS[pixel//25]
    return ascii_str

def to_greyscale(image):
    return image.convert("L")

def resize(image, new_width = 100):
    old_width, old_height = image.size
    new_height = int(new_width * old_height / old_width)
    return image.resize((new_width, new_height))

def ascii(image_path):
    try:
        image = PIL.Image.open(image_path)
    except Exception as e:
        print(f"{image_path} 无法打开,错误信息: {e}")
        return ""
    image = resize(image)
    greyscale_image = to_greyscale(image)
    ascii_str = pixel_to_ascii(greyscale_image)
    img_width = greyscale_image.width
    ascii_str_len = len(ascii_str)
    ascii_img=""
    for i in range(0, ascii_str_len, img_width):
        ascii_img += ascii_str[i:i+img_width] + "\n"
    return ascii_img

修正后的调用代码片段

while success:
    success, image = vidcap.read()
    if not success:  # 读取失败时退出循环,避免无效操作
        break
    frame_filename = f"frame{count}.jpg"
    cv2.imwrite(frame_filename, image)
    print ("Saved frame ", count)
    with open(f"ascii{count}.txt", "w") as f:
        f.write(ascii(frame_filename))
    print("Saved ascii frame ", count)
    count += 1
    time.sleep(0.2)

内容的提问来源于stack exchange,提问作者Lava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:30:39