【Python】【图像处理】图片压缩方法

一直想找个“无损压缩”的办法。
当然这并非真的无损。
我采用了Opencv的处理图像相关的方法。
请见代码:

注意:

opencv安装:pip install opencv-python 或者 conda install opencv

别想不开 install cv2 ……

点击查看代码
# -*- coding: UTF-8 -*-
# 开发人员:萌狼蓝天
# 博客:Https://mllt.cc
# 笔记:Https://cnblogs.com/mllt
# 哔哩哔哩/微信公众号:萌狼蓝天
# 开发时间:2022/10/21
import urllib.parse as  parse

import cv2 as cv
from PIL import Image
import numpy as np
import os
def zipJPG(img,level,outpath):
    img = parse.unquote(img)
    outpath=parse.unquote(outpath)
    print(img)
    img=img.replace("%20"," ")
    outpath = outpath.replace("%20", " ")
    print(img)
    img = Image.open(img)  # 避免P模式图片造成异常
    # print(img.mode)
    # 转换图片模式为RGB
    img = img.convert("RGB")
    img = cv.cvtColor(np.asarray(img), cv.COLOR_RGB2BGR)
    # 转换为np数组
    # [1]cv.IMREAD_COLOR:加载彩色图像,任何图像的透明度都会被忽略,它是默认标志
    # [0]cv.IMREAD_GRAYSCALE:以灰度模式加载图像
    # [-1]cv.IMREAD_UNCHANGED:加载图像,包括 alpha 通道
    try:
        level=int(level)
    except:
        return "ERROR-IMG-ZIP-JPG-LEVEL"
    if level>100:
        level=100
    if level<0:
        level=0
    try:
        cv.imwrite("./temp.jpg",img,[cv.IMWRITE_JPEG_QUALITY,level])
        img = Image.open("temp.jpg")
        img.save(outpath)
        if(os.path.exists(outpath)):
            return outpath
        else:
            return "ERROR-IMG-ZIP-JPG-WRITE"
    except Exception as e:
        print(e)
        return "ERROR-IMG-ZIP-JPG-DEAL"
    # 对于JPEG格式的图片,这个参数表示从0 - 100的图片质量(CV_IMWRITE_JPEG_QUALITY), 默认值是95.
    #
    # 对于PNG格式的图片,这个参数表示压缩级别(CV_IMWRITE_PNG_COMPRESSION)从0 - 9.较高的值意味着更小的尺寸和更长的压缩时间而默认值是3.
    #
    # 对于PPM,PGM或PBM格式的图片,这个参数表示一个二进制格式标志(CV_IMWRITE_PXM_BINARY),取值为0或1,而默认值为1.
    # 判断文件是否存在,存在则返回成功,失败则返回失败

如果要做成接口的话,可以这样

点击查看代码
# -*- coding: UTF-8 -*-
# 开发人员:萌狼蓝天
# 博客:Https://mllt.cc
# 笔记:Https://cnblogs.com/mllt
# 哔哩哔哩/微信公众号:萌狼蓝天
# 开发时间:2022/10/21
import base64
import json

from fastapi import FastAPI, Query
from pydantic import  BaseModel
# uvicorn main:app --reload
import img.PicDeal
app = FastAPI()
@app.get("/img")
def hello():
    return {"Hello": "World"}

@app.post('/img/zip/jpg')
async def img_zip_jpg(img,level,outpath):
    result = PicDeal.zipJPG(img,level,outpath=outpath)
    state="1"
    if(result=="ERROR-IMG-ZIP-JPG-WRITE"):
        state="0"
    if (result == "ERROR-IMG-ZIP-JPG-DEAL"):
        state = "-1"
    if(result=="ERROR-IMG-ZIP-JPG-LEVEL"):
        state="-2"
    return {"data":[{"state":state},{"result":result}]}
class Imgs(BaseModel):
    imgs = [] # type: list[str]
    level ="" # type: str
    outpath = [] # type: list[str]
@app.post('/img/zip/jpg/many')
async def img_zip_jpg(Imgs:Imgs):
    print(Imgs)
    result=[]
    for i in range(len(Imgs.imgs)):
        r= PicDeal.zipJPG(Imgs.imgs[i], Imgs.level, Imgs.outpath[i])
        state="1"
        if r== "ERROR-IMG-ZIP-JPG-WRITE":
            state="0"
        if r == "ERROR-IMG-ZIP-JPG-DEAL":
            state = "-1"
        if r== "ERROR-IMG-ZIP-JPG-LEVEL":
            state="-2"
        result.append({"state": state, "result": r})
    return {"data":{"result":result}}

下面是我做的。

image

image

image

手机拍的照片,1.84MB压缩成468kb(默认75)情况下
手机拍的照片,2.56MB压缩成532kb(默认50)情况下

posted @ 2023-02-25 21:26  萌狼蓝天  阅读(86)  评论(0编辑  收藏  举报