我只想打开文件夹中的图像文件,如果它们还没有jpeg,则将它们转换为jpeg。唯一的问题是我需要将文件保存在内存中,而不是文件。原因是,实际上我正在从tfrecod文件(tensorflow数据文件格式(中读取图像,从中提取图像,检查文件格式,如果不是jpeg,则转换为jpeg,然后在正确解码后写回tfrecord文件。因为不幸的是,张量流对象检测 api 不接受 jpeg 以外的任何图像格式。无论如何,这只是我需要它的解释。
为了能够做到这一点,我需要将文件保存在内存中。所以这是我的代码:
for counter, filename_with_path in enumerate(filenames):
e = next(iter(tf.data.TFRecordDataset([filename_with_path])))
example = tf.train.Example()
example.ParseFromString(e.numpy())
parsed = example.features.feature
image_raw = parsed['image/encoded'].bytes_list.value[0]
# After this point is important
stream = BytesIO(image_raw)
image = Image.open(stream) # Image is pillow image
stream.close()
if image.format != 'JPEG':
tempFile = BytesIO()
image.convert('RGB')
image.save(tempFile, format="JPEG")
newStream = BytesIO(tempFile)
img = Image.open(newStream)
newStream.close()
print(filename, image.format)
print(filename, img.format)
当我运行这个时,我ValueError: I/O operation on closed file.
image.save(tempFile, format="JPEG")
知道为什么这会产生错误吗?我认为这是写入内存文件的建议方法:如何使用 PIL 将 PNG 图像写入字符串?
错误不是关于tempFile
而是关于stream
。在完成image
之前,您不应该执行stream.close()
。这是一个惰性 API,因此它可以更有效地处理大图像。
for counter, filename_with_path in enumerate(filenames):
...
stream = BytesIO(image_raw)
image = Image.open(stream) # Image is pillow image
# remove this line:
# stream.close()
if image.format != 'JPEG':
tempFile = BytesIO()
image.convert('RGB')
image.save(tempFile, format="JPEG")
# this wants bytes, not another BytesIO object, so read it
newStream = BytesIO(tempFile.read())
img = Image.open(newStream)
# same thing, don't close until you are done with img
# newStream.close()
print(filename, image.format)
print(filename, img.format)
来自枕头的图像.打开文档:
这是一个惰性操作;此函数标识文件,但文件保持打开状态,并且在您尝试处理数据(或调用 load(( 方法(之前不会从文件中读取实际的图像数据。