Python——python3版本解决ImageFile.

mac2026-08-04  16

前言:

     还是tornado迁移python3版本项目,图片验证码使用内存保存时候验证码出不来,报了TypeError: string argument expected, got 'bytes';

具体报错如下:

[E 191102 15:11:44 web:1788] Uncaught exception GET /api/piccode?pre=&cur=88508b02-5c21-4ff4-a7eb-dcf01ceb35bf (::1) HTTPServerRequest(protocol='http', host='localhost:8090', method='GET', uri='/api/piccode?pre=&cur=88508b02-5c21-4ff4-a7eb-dcf01ceb35bf', version='HTTP/1.1', remote_ip='::1') Traceback (most recent call last): File "/Users/dongchao/.virtualenvs/py_django/lib/python3.7/site-packages/PIL/ImageFile.py", line 498, in _save fh = fp.fileno() io.UnsupportedOperation: fileno During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/dongchao/.virtualenvs/py_django/lib/python3.7/site-packages/tornado/web.py", line 1697, in _execute result = method(*self.path_args, **self.path_kwargs) File "/Users/dongchao/Desktop/TornadoProjectDome/ihome_tornado/handlers/VerifyCode.py", line 20, in get name,text,pic = captcha.generate_captcha() File "/Users/dongchao/Desktop/TornadoProjectDome/ihome_tornado/utils/captcha/captcha.py", line 220, in generate_captcha return self.captcha("") File "/Users/dongchao/Desktop/TornadoProjectDome/ihome_tornado/utils/captcha/captcha.py", line 213, in captcha image.save(out, format=fmt) File "/Users/dongchao/.virtualenvs/py_django/lib/python3.7/site-packages/PIL/Image.py", line 2084, in save save_handler(self, fp, filename) File "/Users/dongchao/.virtualenvs/py_django/lib/python3.7/site-packages/PIL/JpegImagePlugin.py", line 770, in _save ImageFile._save(im, fp, [("jpeg", (0, 0) + im.size, 0, rawmode)], bufsize) File "/Users/dongchao/.virtualenvs/py_django/lib/python3.7/site-packages/PIL/ImageFile.py", line 513, in _save fp.write(d) TypeError: string argument expected, got 'bytes'

追踪了下问题原因,2版本是使用StringIO操作的,3版本被我直接改成了io.StringIO(),出错原因就是这里写入保存时候应该是bytes,StringIO方法有问题;

解决办法参考简书CoderZb文章,切换方法:

#from cStringIO import StringIO #原方法 import io def captcha(self, path=None, fmt='PNG'): """Create a captcha. Args: path: save path, default None. fmt: image format, PNG / JPEG. Returns: A tuple, (name, text, StringIO.value). For example: ('fXZJN4AFxHGoU5mIlcsdOypa', 'JGW9', '\x89PNG\r\n\x1a\n\x00\x00\x00\r...') """ image = Image.new('RGB', (self.width, self.height), (255, 255, 255)) image = self.background(image) image = self.text(image, self.fonts, drawings=['warp', 'rotate', 'offset']) image = self.curve(image) image = self.noise(image) image = self.smooth(image) name = "".join(random.sample(string.ascii_lowercase + string.ascii_uppercase + '3456789', 24)) text = "".join(self._text) out = io.BytesIO() image.save(out, format=fmt) if path: image.save(os.path.join(path, name), fmt) return name, text, out.getvalue() def generate_captcha(self): self.initialize() return self.captcha("") captcha = Captcha.instance()

先导入from io import BytesIO,然后将out = StringIO()改成out = BytesIO()

最新回复(0)