使用io.BytesIO()
將圖像保存到內存中。它也可能是更好的從原始文件中的每個時間進行如下調整:
from PIL import Image
import os
import io
def compress(original_file, max_size, scale):
assert(0.0 < scale < 1.0)
orig_image = Image.open(original_file)
cur_size = orig_image.size
while True:
cur_size = (int(cur_size[0] * scale), int(cur_size[1] * scale))
resized_file = orig_image.resize(cur_size, Image.ANTIALIAS)
with io.BytesIO() as file_bytes:
resized_file.save(file_bytes, optimize=True, quality=95, format='jpeg')
if file_bytes.tell() <= max_size:
file_bytes.seek(0, 0)
with open(original_file, 'wb') as f_output:
f_output.write(file_bytes.read())
break
compress(r"c:\mytest.jpg", 10240, 0.9)
因此,這將需要該文件,直到達到一個合適的大小規模下來0.9
每次嘗試。然後它會覆蓋原始文件。
作爲一個替代方法,你可以創建秤的列表嘗試,例如[0.01, 0.02 .... 0.99, 1]
然後使用二進制印章,以確定哪些規模的結果在最近的一個文件大小來max_size
如下:
def compress(original_file, max_size):
save_opts={'optimize':True, 'quality':95, 'format':'jpeg'}
orig_image = Image.open(original_file)
width, height = orig_image.size
scales = [scale/1000 for scale in range(1, 1001)] # e.g. [0.001, 0.002 ... 1.0]
lo = 0
hi = len(scales)
while lo < hi:
mid = (lo + hi) // 2
scaled_size = (int(width * scales[mid]), int(height * scales[mid]))
resized_file = orig_image.resize(scaled_size, Image.ANTIALIAS)
file_bytes = io.BytesIO()
resized_file.save(file_bytes, **save_opts)
size = file_bytes.tell()
print(size, scales[mid])
if size < max_size:
lo = mid + 1
else:
hi = mid
scale = scales[max(0, lo-1)]
print("Using scale:", scale)
orig_image.resize((int(width * scale), int(height * scale)), Image.ANTIALIAS).save(original_file, **save_opts)
所以對於10000
一個max_size
,循環首先嚐試的0.501
規模,如果過大0.251
受審等等。當max_size=1024
將嘗試以下比例:
180287 0.501
56945 0.251
17751 0.126
5371 0.063
10584 0.095
7690 0.079
9018 0.087
10140 0.091
9336 0.089
9948 0.09
Using scale: 0.09
您不清楚您要做什麼。循環調整圖像大小,因此保存是必要的。如果你想要的只是尺寸信息,那麼不要調整大小或保存文件。 – aris
我假設你保存爲JPEG格式。通過將文件數據保存到內存中的BytesIO對象而不是磁盤,可以節省一些時間。這也將使得獲得最終文件大小的速度更快。但是,它不會加速編碼過程。順便說一句,使用質量95沒有太大的意義。它非常慢,它產生大文件大小,90和95之間的視覺差異很少引人注意。根據圖像的性質,85通常是相當不錯的。 –
我還要提到的是,圖像中PIL /枕頭縮放程序是不是質量非常高,雖然你可能沒有注意到,如果圖像是足夠大,並且是有很多平滑色調過渡,而不是計算機生成圖像的照片有很多高對比度的區域。此外,你應該**不**逐步編輯JPEG。不要保存縮放的圖像,然後重新加載它,並重新縮放已縮放的圖像。這樣會很快失去質量。如果您必須嘗試不同的縮放比例,直到文件大小足夠小,從原始文件生成每個新版本。 –