在 xlsxwriter 中以可读的方式缩放图像
Scale images in a readable manner in xlsxwriter
我正在使用 xlsxwriter 在 excel 单元格中插入图像及其元数据。但我似乎无法以可读的方式正确缩放它。
我的代码是:
def resize_image(path,name):
img=Image.open(path)
img= img.resize((512,512))
global temp_path
full_path=os.path.join(temp_path,name)
img.save(full_path)
return full_path
def rotate_image(path ,name):
img=Image.open(path)
img= img.rotate(90,Image.NEAREST, expand=1)
global temp_path
full_path=os.path.join(temp_path,name)
img.save(full_path)
return full_path
def scale(size):
row=100
col=50
return (row/size[0],col/size[1])
row=1
workbook=xlsxwriter.Workbook('data.xlsx')
bold = workbook.add_format({'bold': True})
worksheet=workbook.add_worksheet()
wrap = workbook.add_format({'text_wrap': True})
worksheet.set_column(1,4,50 ,wrap)
worksheet.write('A1','Image Name',bold)
worksheet.write('B1',"Resized Image",bold)
worksheet.write('C1',"Rotated Image",bold)
worksheet.write('D1',"Metadata",bold)
for i in glob.iglob(path+'\*.jpg',recursive=True):
col=0
size=np.asarray(Image.open(i)).shape
x,y=scale(size)
worksheet.set_row(row,50,wrap)
name=get_image_name(i)
worksheet.write(row,col, name)
col+=1
worksheet.insert_image(row,col,resize_image(i,name),{'x_scale':x, 'y_scale':y,'object_position': 1})
col+=1
worksheet.insert_image(row,col,rotate_image(i,name),{'x_scale':x, 'y_scale':y,'object_position': 1})
col+=1
worksheet.write(row,col,get_metadata(i),wrap)
row+=1
workbook.close()
我得到的输出是 output and I need something like this desired output。有人能告诉我我做错了什么吗?我试过缩放、改变宽度和高度等,但 none 似乎有效。
编辑这里是我的代码,在评论中进行了更改:
image_data={}
row=1
workbook=xlsxwriter.Workbook('data.xlsx')
bold = workbook.add_format({'bold': True})
worksheet=workbook.add_worksheet()
wrap = workbook.add_format({'text_wrap': True})
worksheet.set_column(4,4,50)
worksheet.set_column(1,3,32)
worksheet.set_column(0,0,20)
worksheet.write('A1','Image Name',bold)
worksheet.write('B1',"Resized Image",bold)
worksheet.write('C1',"Rotated Image",bold)
worksheet.write('D1',"Metadata",bold)
for i in glob.iglob(path+'\*.jpg',recursive=True):
col=0
size=np.asarray(Image.open(i)).shape
x,y=scale(size)
worksheet.set_row(row,64)
name=get_image_name(i)
worksheet.write(row,col, name)
col+=1
worksheet.insert_image(row,col,resize_image(i,name),{'x_scale':x, 'y_scale':y})
col+=1
worksheet.insert_image(row,col,rotate_image(i,name),{'x_scale':x, 'y_scale':y})
col+=1
s=get_metadata(i)
if(len(s)!=0):
worksheet.write(row,col,s,wrap)
image_data[name]=s
else:
print('No Metadata found for image {}'.format(name))
row+=1
workbook.close()
我没有找到自动找到正确的列和行宽以进行缩放的解决方案,但也许这个解决方案可以帮助您。
import glob
import io
import os
from typing import Tuple
import xlsxwriter
from pil import Image
def buffer_image(image: Image, format: str = 'JPEG'):
# Store image in buffer, so we don't have to write it to disk.
buffer = io.BytesIO()
image.save(buffer, format=format)
return buffer, image
def resize(path: str, size: Tuple[int, int], format='JPEG'):
image = Image.open(path)
image = image.resize(size)
return buffer_image(image, format)
def rotate(image: Image, rotation: int = 90, format='JPEG'):
image = image.rotate(rotation, Image.NEAREST, expand=1)
return buffer_image(image, format)
def create_header(worksheet: xlsxwriter.workbook.Worksheet):
bold = workbook.add_format({'bold': True})
worksheet.write('A1', 'Image Name', bold)
worksheet.write('B1', "Resized Image", bold)
worksheet.write('C1', "Rotated Image", bold)
worksheet.write('D1', "Metadata", bold)
return worksheet
if __name__ == '__main__':
workbook = xlsxwriter.Workbook('image.xlsx')
worksheet = workbook.add_worksheet()
# Update the worksheet.
wrap = workbook.add_format({'text_wrap': True})
worksheet.set_column(0, 4, 27.5, wrap)
worksheet = create_header(worksheet)
for row, path in enumerate(glob.iglob("images/*.jpg"), start=1):
worksheet.set_row(row, 150, wrap)
# Add image name
worksheet.write(row, 0, os.path.basename(path))
# Add images
image_buffer, image = resize(path, (512, 512), format='JPEG')
data = {'x_scale': 200 / image.width, 'y_scale': 200 / image.height, 'object_position': 1}
worksheet.insert_image(row, 1, path, {'image_data': image_buffer, **data})
image_buffer, image = rotate(image, 90, format='JPEG')
worksheet.insert_image(row, 2, path, {'image_data': image_buffer, **data})
# Add metadata
worksheet.write(row, 3, "Meta data", wrap)
workbook.close()
方法
我手动检查了列和行的首选大小,以修复图像大小 (200, 200)。列和行的值分别为 27.5
和 150
。
查看行:
worksheet.set_column(0, 4, 27.5, wrap)
worksheet.set_row(row, 150, wrap)
由于我现在知道了一个固定的缩放比例,我可以通过将其与已知的 (200, 200) 的情况进行比较来计算其他图像尺寸
data = {'x_scale': 200 / image.width, 'y_scale': 200 / image.height, 'object_position': 1}
额外
我没有将临时图像写入磁盘,而是使用缓冲区将图像保存在内存中,这大约快两倍。
def buffer_image(image: Image, format: str = 'JPEG'):
# Store image in buffer, so we don't have to write it to disk.
buffer = io.BytesIO()
image.save(buffer, format=format)
return buffer, image
图像格式对缓冲区很重要,因此 resize
和 rotate
函数中有一个 format
参数。如果您使用 .png
图片 JPEG
必须更改为 PNG
。
我正在使用 xlsxwriter 在 excel 单元格中插入图像及其元数据。但我似乎无法以可读的方式正确缩放它。
我的代码是:
def resize_image(path,name):
img=Image.open(path)
img= img.resize((512,512))
global temp_path
full_path=os.path.join(temp_path,name)
img.save(full_path)
return full_path
def rotate_image(path ,name):
img=Image.open(path)
img= img.rotate(90,Image.NEAREST, expand=1)
global temp_path
full_path=os.path.join(temp_path,name)
img.save(full_path)
return full_path
def scale(size):
row=100
col=50
return (row/size[0],col/size[1])
row=1
workbook=xlsxwriter.Workbook('data.xlsx')
bold = workbook.add_format({'bold': True})
worksheet=workbook.add_worksheet()
wrap = workbook.add_format({'text_wrap': True})
worksheet.set_column(1,4,50 ,wrap)
worksheet.write('A1','Image Name',bold)
worksheet.write('B1',"Resized Image",bold)
worksheet.write('C1',"Rotated Image",bold)
worksheet.write('D1',"Metadata",bold)
for i in glob.iglob(path+'\*.jpg',recursive=True):
col=0
size=np.asarray(Image.open(i)).shape
x,y=scale(size)
worksheet.set_row(row,50,wrap)
name=get_image_name(i)
worksheet.write(row,col, name)
col+=1
worksheet.insert_image(row,col,resize_image(i,name),{'x_scale':x, 'y_scale':y,'object_position': 1})
col+=1
worksheet.insert_image(row,col,rotate_image(i,name),{'x_scale':x, 'y_scale':y,'object_position': 1})
col+=1
worksheet.write(row,col,get_metadata(i),wrap)
row+=1
workbook.close()
我得到的输出是 output and I need something like this desired output。有人能告诉我我做错了什么吗?我试过缩放、改变宽度和高度等,但 none 似乎有效。
编辑这里是我的代码,在评论中进行了更改:
image_data={}
row=1
workbook=xlsxwriter.Workbook('data.xlsx')
bold = workbook.add_format({'bold': True})
worksheet=workbook.add_worksheet()
wrap = workbook.add_format({'text_wrap': True})
worksheet.set_column(4,4,50)
worksheet.set_column(1,3,32)
worksheet.set_column(0,0,20)
worksheet.write('A1','Image Name',bold)
worksheet.write('B1',"Resized Image",bold)
worksheet.write('C1',"Rotated Image",bold)
worksheet.write('D1',"Metadata",bold)
for i in glob.iglob(path+'\*.jpg',recursive=True):
col=0
size=np.asarray(Image.open(i)).shape
x,y=scale(size)
worksheet.set_row(row,64)
name=get_image_name(i)
worksheet.write(row,col, name)
col+=1
worksheet.insert_image(row,col,resize_image(i,name),{'x_scale':x, 'y_scale':y})
col+=1
worksheet.insert_image(row,col,rotate_image(i,name),{'x_scale':x, 'y_scale':y})
col+=1
s=get_metadata(i)
if(len(s)!=0):
worksheet.write(row,col,s,wrap)
image_data[name]=s
else:
print('No Metadata found for image {}'.format(name))
row+=1
workbook.close()
我没有找到自动找到正确的列和行宽以进行缩放的解决方案,但也许这个解决方案可以帮助您。
import glob
import io
import os
from typing import Tuple
import xlsxwriter
from pil import Image
def buffer_image(image: Image, format: str = 'JPEG'):
# Store image in buffer, so we don't have to write it to disk.
buffer = io.BytesIO()
image.save(buffer, format=format)
return buffer, image
def resize(path: str, size: Tuple[int, int], format='JPEG'):
image = Image.open(path)
image = image.resize(size)
return buffer_image(image, format)
def rotate(image: Image, rotation: int = 90, format='JPEG'):
image = image.rotate(rotation, Image.NEAREST, expand=1)
return buffer_image(image, format)
def create_header(worksheet: xlsxwriter.workbook.Worksheet):
bold = workbook.add_format({'bold': True})
worksheet.write('A1', 'Image Name', bold)
worksheet.write('B1', "Resized Image", bold)
worksheet.write('C1', "Rotated Image", bold)
worksheet.write('D1', "Metadata", bold)
return worksheet
if __name__ == '__main__':
workbook = xlsxwriter.Workbook('image.xlsx')
worksheet = workbook.add_worksheet()
# Update the worksheet.
wrap = workbook.add_format({'text_wrap': True})
worksheet.set_column(0, 4, 27.5, wrap)
worksheet = create_header(worksheet)
for row, path in enumerate(glob.iglob("images/*.jpg"), start=1):
worksheet.set_row(row, 150, wrap)
# Add image name
worksheet.write(row, 0, os.path.basename(path))
# Add images
image_buffer, image = resize(path, (512, 512), format='JPEG')
data = {'x_scale': 200 / image.width, 'y_scale': 200 / image.height, 'object_position': 1}
worksheet.insert_image(row, 1, path, {'image_data': image_buffer, **data})
image_buffer, image = rotate(image, 90, format='JPEG')
worksheet.insert_image(row, 2, path, {'image_data': image_buffer, **data})
# Add metadata
worksheet.write(row, 3, "Meta data", wrap)
workbook.close()
方法
我手动检查了列和行的首选大小,以修复图像大小 (200, 200)。列和行的值分别为 27.5
和 150
。
查看行:
worksheet.set_column(0, 4, 27.5, wrap)
worksheet.set_row(row, 150, wrap)
由于我现在知道了一个固定的缩放比例,我可以通过将其与已知的 (200, 200) 的情况进行比较来计算其他图像尺寸
data = {'x_scale': 200 / image.width, 'y_scale': 200 / image.height, 'object_position': 1}
额外
我没有将临时图像写入磁盘,而是使用缓冲区将图像保存在内存中,这大约快两倍。
def buffer_image(image: Image, format: str = 'JPEG'): # Store image in buffer, so we don't have to write it to disk. buffer = io.BytesIO() image.save(buffer, format=format) return buffer, image
图像格式对缓冲区很重要,因此
resize
和rotate
函数中有一个format
参数。如果您使用.png
图片JPEG
必须更改为PNG
。