PowerToys icon indicating copy to clipboard operation
PowerToys copied to clipboard

Image Resize to a specified Maximum FileSize (e.g. Make my image <3MB)

Open tyeth opened this issue 2 years ago • 1 comments

Description of the new feature / enhancement

Image Resizer would support file size in kilobytes (megabytes etc) as a specified output size/option. To achieve that the program would first try saving using the current advanced output settings (e.g. jpg at 95% compression) and then look at the current file size, and if not below the threshold then reduce the image scale by 5-50% (conservative reduction unless over threshold by a factor of 10? 30? 100?) and keep repeating until the desired filesize was achieved.

I have a folder of files and want them all to be no more than 3mb to comply with an online platform that I upload to. They are all different sizes, resolutions and aspect ratios.

Scenario when this would be used?

I regularly download a collection of images from google photos when doing a project write up, or to send to someone. Sending 15megabyte images isn't always appreciated over email, and some online services have maximum file sizes for images.

Supporting information

It is a ridiculously laborious process to do each image manually. I usually just pick a really brutal percentage reduction and degrade all images unnecessarily far rather than reduce each one manually/individually.

image

tyeth avatar Jan 10 '24 22:01 tyeth

I tried something along these lines, but it was a bit brutal / unpredictable, and the warning about a decompression bomb was amusing image

import os
from PIL import Image

def reduce_image_size(folder_path, target_size=3000000):
    for filename in os.listdir(folder_path):
        if filename.endswith('.mp4'):
            continue

        file_path = os.path.join(folder_path, filename)
        if not os.path.isfile(file_path):
            continue

        with Image.open(file_path) as img:
            width, height = img.size

            while os.path.getsize(file_path) > target_size:
                width, height = (int(width * 0.9), int(height * 0.9))
                img = img.resize((width, height), Image.BICUBIC)
                img.save(file_path)

                if width < 100 or height < 100:
                    break  # Avoid making the image too small

if __name__ == "__main__":
    folder = input("Enter the folder path: ")
    folder = folder if folder else os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ikea_photos')
    print(folder)
    size = input("Enter target size in bytes (default 3000000): ")
    size = int(size) if size else 3000000
    reduce_image_size(folder, size)

tyeth avatar Jan 10 '24 23:01 tyeth

I don't have any suggestions for implementation, but I also often see file size as a limiting factor for uploading, and I, too, would like to say a maximum file size and have as a result the largest, clearest image whose file size is less than a given file size.

I left a similar comment on a previous enhancement request issue that is identical: issue #20120 ImageResizer: Additional option to resize images based on filesize instead of resolution by PulsarNeutronStar

Thanks for your efforts, folks.

jefferydecker avatar Feb 19 '24 13:02 jefferydecker

/dup https://github.com/microsoft/PowerToys/issues/8790

crutkas avatar Mar 22 '24 19:03 crutkas

Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report!