使用PIL python基于文件大小计算图像分辨率



我想根据所需的文件大小,使用resize()方法从PIL调整图像的大小。例如,我有一个图像文件大小为14.1 MB,宽度x高度为3456 x 5184。如果所需的文件大小为2mb,它的分辨率将是多少??我自己尝试了一些计算,比如使用这个公式image_size = (width * height * bit_depth + headers) / 8加上纵横比从图像的当前状态,但它不像我预期的那样工作。

目标:

查找所需的高度或宽度

已知:

  1. 期望文件大小
  2. 当前文件大小
  3. 当前分辨率(宽x高)

如何将jpeg大小减小到'所需大小'?Python PIL:查找图像的大小而不将其写入文件

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 27 18:26:54 2021
@author: Pietro
"""
import io
from PIL import Image
def SaveWithTargetFileSize(im, filename, target):

x, y =im.size
buffer = io.BytesIO()
im.save(buffer, format=mod_img, quality=100)
im_size = buffer.getbuffer().nbytes

if im_size <= target:
print('invalid target value ')
return
while im_size > target :


buffer = io.BytesIO()
im.save(buffer, format=mod_img, quality=100)
im_size = buffer.getbuffer().nbytes

im = im.resize((x,y))
# print(x,y  ,'      ', im_size)
x -= 1
y -= 1


print('image_size for target file_size :', im.size[0],' X ', im.size[1] ,'  image_file_size  :', im_size)
im.save(filename+'.'+mod_img.lower(), format=mod_img, quality=100)

im = Image.open('Immagine_6.tif')
x, y =im.size
typ_img = im.mode
mod_img = im.format
print('image size : ',x,' X ',y,'   ',' image_type :', typ_img,'     image_format :', mod_img)

SaveWithTargetFileSize(im, "result_2", 400000) # here the target values in bytes

您需要计算出以字节为单位的文件大小目标(或在代码中添加转换器)

速度很慢,因为每次从初始值到目标值只调整1个像素

也许别人会用最快的方法。

根据@thebjorn的建议,我尝试对分搜索

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 27 18:26:54 2021
@author: Pietro
"""
import io
from PIL import Image
from datetime import datetime
begin = datetime.now()

def SaveWithTargetFileSize(im, filename, target):
xmax, ymax = im.size
xmin = 0
ymin = 0
buffer = io.BytesIO()
im.save(buffer, format=mod_img, quality=100)
im_size = buffer.getbuffer().nbytes

im_size_original = im_size
if im_size <= target:
print('invalid target value ')
return
numGuesses = 0
while xmin < xmax and ymin < ymax:
x_x, y_y = (xmax - xmin)//2, (ymax - ymin)//2
im = im.resize((x_x, y_y))
buffer = io.BytesIO()
im.save(buffer, format=mod_img, quality=100)
im_size = buffer.getbuffer().nbytes

#print(im.size[0], im.size[1], '      ', im_size, '    guesses :',
#      numGuesses, '   ', im_size,  target, x_x, y_y, xmax, ymax, xmin, #ymin)
if im_size < target:
xmax += x_x
ymax += y_y
elif im_size > target:
xmax -= x_x
ymax -= y_y

if abs(im_size - target) < (target*1)//100:
if im_size > target:
approx = str(200-(im_size*100/target))
if im_size < target:
approx = str(im_size*100/target)

return print('nbest approximation : ',approx+'%nn',im.size[0],' ', im.size[1], '        ', im_size,
'     guesses : ', numGuesses,
'     ', im_size,' ',  target,' ', x_x,' ', y_y,' ', xmax,' ', ymax,' ', xmin,' ', ymin,' ', im_size_original,'nn',sep='')

print(im.size[0], im.size[1], '      ', im_size, '    guesses :', numGuesses,
'   ', im_size,  target, x_x, y_y, xmax, ymax, xmin, ymin, im_size_original,'nn')
numGuesses += 1
print('image_size for target file_size :',
im.size[0], ' X ', im.size[1], '  image_file_size  :', im_size)
# im.save(filename+'.'+mod_img.lower(), format=mod_img, quality=100)

im = Image.open('Immagine_6.tif')
x, y = im.size
typ_img = im.mode
mod_img = im.format
print('image size : ', x, ' X ', y, '   ', ' image_type :',
typ_img, '     image_format :', mod_img)

SaveWithTargetFileSize(im, "result_5", 558999)
# SaveWithTargetFileSize(im, "result_5", 568000)
# SaveWithTargetFileSize(im, "result_4", 558999000)
print('nTIME : ', datetime.now() - begin)

使用这个图像设置image:图像大小:520 X 409 image_type: RGBA image_format: TIFF它比第一次保存打印行

所花费的时间少一半。

最新更新