前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Python压缩图片成指定大小

使用Python压缩图片成指定大小

原创
作者头像
mariolu
发布2024-05-10 01:32:33
9700
代码可运行
发布2024-05-10 01:32:33
举报
文章被收录于专栏:Python实用主义Python实用主义
运行总次数:0
代码可运行

我们常常上传图片,网站对照片有一定要求,比如说图片大小不能超过多少个kB,图片宽度高度在一个限定值。

平时的你可能会用小画家绘图软件或者PS来处理。既然我们是个程序员,也有了Python这把瑞士军刀。那么本篇文章教你怎么写个代码来处理图片来满足日常需求。有了这个代码以后这种小case也不用求人了。

处理图片分为两个部分:

  • 重制图片成指定宽度和指定高度值,并且能保持长宽比
  • 不改变图片宽度和高度值,压缩JPEG质量比,来使图片保持在一定的存储大小之内。

这里用到的图片处理库就是Python自带的PIL下面的Image Module

一、图片的resize

图片的resize,一般来说我们会维持图片的原始长宽比,来使图片看起来没有失真。

这里的原始长宽比确定,我们会去找长度和高度哪个大。我们先把那个大的值限定在指定长度内,然后再根据长宽比去计算另一个长度值。分情况讨论:

  • 如果原始长高比>目标长高比,那么目标长度定为用户设定值,目标高度根据原始长高比去计算。
  • 反之,目标高度设为用户设定值,目标宽度根据原始长高比去计算。

就是这段代码

代码语言:python
代码运行次数:0
复制
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。

使用的时候需要你需要提供个性化输入:

  • 图片是来自本地磁盘还是网络
  • 目标图片存储空间不超过多少B
  • 目标图片的长度和高度
代码语言:python
代码运行次数:0
复制
#!/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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、图片的resize
  • 二、图片的压缩
  • 三、完整的程序
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档