我们常常上传图片,网站对照片有一定要求,比如说图片大小不能超过多少个kB,图片宽度高度在一个限定值。
平时的你可能会用小画家绘图软件或者PS来处理。既然我们是个程序员,也有了Python这把瑞士军刀。那么本篇文章教你怎么写个代码来处理图片来满足日常需求。有了这个代码以后这种小case也不用求人了。
处理图片分为两个部分:
这里用到的图片处理库就是Python自带的PIL下面的Image Module
图片的resize,一般来说我们会维持图片的原始长宽比,来使图片看起来没有失真。
这里的原始长宽比确定,我们会去找长度和高度哪个大。我们先把那个大的值限定在指定长度内,然后再根据长宽比去计算另一个长度值。分情况讨论:
就是这段代码
max_width=100
min_width=100
max_height=100
min_width=100
new_width=max_width
new_height=max_height
if rgb_im.width/rgb_im.height>new_width/new_height:
new_height=int(new_height*rgb_im.height/rgb_im.width)
else:
new_width=(new_width*rgb_im.width/rgb_im.height)
目标图片是JPEG的话,JPEG有个图片压缩因子。我们的目标是调整这个因子来使得存储尽量接近目标值。换句话说就是不超过存储空间的前提下,调整因子保持最大的图片质量。这里的压缩因子在(25,96)之间。然后采用二分法得出目标压缩因子。也就是代码里的defJPEGSaveWithTargetSize(im, filename, target):函数。
程序如下,或者我已经上传到github这里地址下载https://github.com/lumanyu/ai_app/blob/main/image_compress/main.py。
使用的时候需要你需要提供个性化输入:
#!/usr/local/bin/python3
import io
import math
import sys
from PIL import Image
def JPEGSaveWithTargetSize(im, filename, target):
"""Save the image as JPEG with the given name at best quality that makes less than "target" bytes"""
# Min and Max quality
Qmin, Qmax = 25, 96
# Highest acceptable quality found
Qacc = -1
while Qmin <= Qmax:
m = math.floor((Qmin + Qmax) / 2)
# Encode into memory and get size
buffer = io.BytesIO()
im.save(buffer, format="JPEG", quality=m)
s = buffer.getbuffer().nbytes
if s <= target:
Qacc = m
Qmin = m + 1
elif s > target:
Qmax = m - 1
# Write to disk at the defined quality
if Qacc > -1:
im.save(filename, format="JPEG", quality=Qacc)
im.show()
else:
print("ERROR: No acceptble quality factor found", file=sys.stderr)
################################################################################
# main
################################################################################
# Load sample image
from PIL import Image
import requests
from io import BytesIO
url="https://raw.githubusercontent.com/lumanyu/ai_app/main/data/recipe/braised_pork.png"
response = requests.get(url)
im = Image.open(BytesIO(response.content)) #原始图片来自网络
rgb_im = im.convert('RGB')
#im = Image.open('/Users/mark/sample/images/lena.png') #原始图片来自本地磁盘
# Input Image Limitation
storage=100000 #目标图片存储空间
max_width=100 #目标图片宽度
min_width=100
max_height=100 #目标图片高度
min_width=100
new_width=max_width
new_height=max_height
if rgb_im.width/rgb_im.height>new_width/new_height:
new_height=int(new_height*rgb_im.height/rgb_im.width)
else:
new_width=(new_width*rgb_im.width/rgb_im.height)
resized_im = rgb_im.resize((new_width, new_height), Image.Resampling.LANCZOS)
# Save at best quality under 100,000 bytes
JPEGSaveWithTargetSize(resized_im, "result.jpg", storage)
运行效果如下:
原始图片对比压缩后的图片:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。