在Pillow中合并后的图像尺寸很大

问题描述 投票:0回答:1

这些是我用 python 做的第一个项目,我这样做是出于爱好。我尽力提供代码并解释我的问题。

在我的科学工作中,我经常处理必须合并成一个图形的绘图。我的大多数同事都使用 CorelDraw 或其他一些软件,但如果您在中间某个位置添加新绘图,然后必须更改所有图片和标签,那就很痛苦。

我认为应该有一个简单的方法,将所有图像加载到Python程序中,用字母标记它们,然后将它们组合起来,然后将它们保存为新图像。我的第一次尝试是在 replit 中进行的,效果很好。现在我尝试使用streamlit和github为其制作UI,以便我的同事也可以使用它。

但不知何故,我最终得到了比以前更大的图片(就文件大小而言很大)。每个绘图均从 origin 导出为 tif 文件,大小约为 50kb,300dpi,3.5 英寸。我用 3-8 个图绘制一张图。 当我将它们组合起来时,即使将它们缩小到 1050 像素宽度,它们也有多个 MB。 更令人困惑的是,我可以使用这个 Windows 照片程序并单击“缩小图像”。然后我选择 100% 进行缩放,因此大小没有变化,但现在是 500kb。即使我放大,也看不到任何变化。

在我的 replit 中,我将所有 tif 拖到一个文件夹中,然后将它们加载到一个变量中。

在 Streamlit 中,我使用 st.file_uploader 来上传图像。然后它们被存储在一个变量中。从那里我创建了一个新文件夹并将所有图像存储在那里。 然后我可以使用我在 replit 中使用的相同代码。 5 张图片,每张 50kb,最终形成一个 15MB 的文件。

然后我跳过了“保存在单独的文件夹中”,因为我想也许每次保存/加载都会使它更大。 所以我直接从变量中打开图像,我的文件现在有 5MB。

我从乳胶中知道,每个人都在要求一个最小的工作示例,这似乎有点困难,因为我不知道过程的哪一步出了问题。 但我试图提供主要代码,但不提供所有功能和一些描述。如果还需要任何东西,我很乐意提供。 这是 git 存储库中的完整代码 https://github.com/VonClaussen/image-orientation

还有streamlit应用程序 https://image-orientation.streamlit.app/

import streamlit as st
#here are more imports like PIL, io,  

#upload images
uploaded_files = st.file_uploader("Upload Files", type=["jpg", "png", "jpeg", "tif"], accept_multiple_files=True)

#Load the uploaded files into the variable
image_list = []  # Initialize an empty list to store the uploaded images
filename_list=[]
if uploaded_files:
    for file in uploaded_files:
        # Read the image file and append it to the list
        image_data = file.read()
        image = Image.open(io.BytesIO(image_data))
        image_list.append(image)
        filename_list.append(file.name)
        st.write(f"Opened file: {file.name}")

if st.button('Build figure'):
    # First all images get a label. label info stores all information like font, size, shift of the label etc.
    labeled_images = label_images(image_list, label_info)

    #now the labeled images are handed over to the drawing setup. From the number of images it calculates which images goes into which row/column and returns two variables.
    # row_list stores multiple lists, one for each row. Each list contains the labeled images that go into this row.
    # column_list is like row_list but stores the images of a column.
    row_list, column_list = drawing_setup(labeled_images, number_of_rows,
                                        number_of_columns)
    # the get_dimensions function iterates through all images in a row to termine the max height of that row which is stored in the dictionary max-height with the row index as a key
    # max_widths is the same dictionary for the max width of each column
    #total_height and total_width store the maximum dimensions to create the new image.
    max_heights, max_widths, total_height, total_width = get_dimensions(
        row_list, column_list)
    #final image iterates through the row list. It pastes all the images according to the coordinates that are calculated from max_height and max_width for each image
    final_image = arange_images(row_list, max_heights, max_widths, total_height, total_width, background_color)
    #The following step will reduce the size of the image usally to 3.5 or 7 inch at 300dpi
    small_image=fx.resize(final_image, reduced_width)
    small_image.save('small_image.tif')
    
    #Finally the new image can be downloaded
    with open("small_image.tif", "rb") as file:
      btn = st.download_button(
            label="Download image",
            data=file,
            file_name="small_image.tif",
            mime="image/tif"
          )

python python-imaging-library
1个回答
0
投票

对于您所描述的大小,这只能意味着 tif 的保存完全没有压缩 - 也就是说,每个像素在输出文件上占用完整的 32 位。

只需检查 PIL

.save
保存 tiff 文件的选项,LZW 压缩将为您提供无损文件,并且具有合理的大小。或者直接另存为
.png
,默认压缩。

这里,我在保存tiff时传入了

compression='tiff_lzw'
选项,我的1024x768图像从3MB以上变成了70KB。


In [15]: img.save("test.tif")

In [16]: !ls -l test.tif
-rw-rw-r--. 1 jsbueno jsbueno 3146566 Nov 25 15:41 test.tif

In [17]: img.save("test.tif", compression="tiff_lzw")

In [18]: !ls -l test.tif
-rw-rw-r--. 1 jsbueno jsbueno 74044 Nov 25 15:43 test.tif

不幸的是,Pillow 的文档对于某些主题来说很难阅读,即使对于上述内容,我也只能通过查看源代码来获取 tif 压缩选项。

因此,为了方便其他人到达这里,这些是:

COMPRESSION_INFO = {
    # Compression => pil compression name
    1: "raw",
    2: "tiff_ccitt",
    3: "group3",
    4: "group4",
    5: "tiff_lzw",
    6: "tiff_jpeg",  # obsolete
    7: "jpeg",
    8: "tiff_adobe_deflate",
    32771: "tiff_raw_16",  # 16-bit padding
    32773: "packbits",
    32809: "tiff_thunderscan",
    32946: "tiff_deflate",
    34676: "tiff_sgilog",
    34677: "tiff_sgilog24",
    34925: "lzma",
    50000: "zstd",
    50001: "webp",
}


© www.soinside.com 2019 - 2024. All rights reserved.