Skip to content

pymupdf.Page.replace_image() will save an image stream file 2 times #4327

Closed

Description

@Muolae

Description of the bug

new_xref = page.insert_image( page.rect, filename=filename, stream=stream, pixmap=pixmap ) doc.xref_copy(new_xref, xref) # copy over new to old

the code doc.xref_copy(new_xref, xref)copy the stream of new_image to the old xref,but it do not delete the stream of new_image. this bug will result in the old xref and the new_xref Point to the same data, and the same data is stored 2 times in the pdf file.

I want to replace the original picture with a smaller one.However, I found that the file size after replacement is more than the file size obtained by directly deleting the image plus the volume of the replaced image, which is exactly equal to the size of the image file used to replace, so I guess the file is actually stored twice.I looked at the source code and came to the conclusion above.

I add
page.delete_image(new_xref)
after it can Fix this,but I think it has batter solution.

Image

How to reproduce the bug

use pymupdf.Page.replace_image to change image size,then look the change of size of pdf file.
sorry my English is bad.

PyMuPDF version

1.25.2

Operating system

Windows

Python version

3.9

Activity

  1. JorjMcKie commented on Feb 25, 2025

    @JorjMcKie
    Collaborator

    I don't understand what you are actually doing: please provide your PDF and your script.
    We cannot deal with issues that do not follow the requirements as stated in the bug issue form.

    One intermediate comment though:
    When saving the PDF after replacing / deleting an image make sure to use garbage collection and compression options so that the old data is removed! Recommended is using doc.ez_save().

  2. Muolae commented on Feb 25, 2025

    @Muolae
    Author

    I want to replace the original image in the pdf file with a smaller image, my program extracts each image in the file, then uses a compression function to reduce their size, and then replaces the original image. But I found that for example, if I delete all the pictures directly, the resulting file size is 1MB, and if I replace the original picture with a total size of 2MB, I get a file with a size of 5MB. I think the reasonable size is 3MB.This means that these pictures store two copies of the same data in a pdf file.Thank you for your reply
    ` for page in doc.pages():
    imageList = page.get_images()

        for imginfo in imageList:
            xref = imginfo[0]  # 获取图像的 xref
            image_info = doc.extract_image(xref)
    
            # 保存图像到文件
            new_name = f"./src/temp/image_{xref}.{image_info['ext']}"
            with open(new_name, "wb") as img_file:
                img_file.write(image_info["image"])
            img = imgopen(new_name)
            pix_size += img.height * img.width * 3 // 1024
            img_size+=os.path.getsize(new_name) / 1024
    
            loc = page.get_image_rects(imginfo)
            # doc._deleteObject(imginfo[0])
            page.delete_image(xref)
            compressed_image_name = new_name.replace(new_name.split(".")[-1], 'jpg')
            picCompress.compress_by_quality(new_name, compressed_image_name, quality=15)
            zimg_size+=os.path.getsize(compressed_image_name)/1024
            # page.insert_image(loc[0], filename=compressed_image_name,overlay=False)
            page.replace_image(xref, filename=compressed_image_name)
            # my_replace(page,xref,filename=compressed_image_name)
        now_page += 1
        # ws.send("reg:" + str(int(100 * now_page / page_number)))
    # print("图片面积大小:", pix_size, "KB")
    # print("图片实际大小:", img_size, "KB")
    # print("图片压缩大小:", zimg_size, "KB")
    # 计算无图片文件大小
    doc.ez_save(filename='./out/out.pdf')`
    
  3. JorjMcKie commented on Feb 25, 2025

    @JorjMcKie
    Collaborator

    I see no issue here, but rather a request for help. Moving this to "Discussions".

  4. locked and limited conversation to collaborators on Feb 25, 2025
  5. converted this issue into a discussion #4328 on Feb 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions