引言

在真实项目中,往往要进行图片的传输和视频的传输,但因为用户上传的图片和视频所占用的大小问题而导致占用服务器的空间多,并且用户访问这些图片的时候因为图片或视频太大而长时间加载,所以要对用户上传的视频和图片进行压缩,减少服务器的占用空间和加载时间。

1.新建一个类

我们先新建一个保存图片或视频的一个类

import platformclass Compress_Pic_or_Video(object):def __init__(self,filePath,inputName,outName=""):self.filePath = filePath  #文件地址self.inputName = inputName  #输入的文件名字self.outName = outName  #输出的文件名字self.system_ = platform.platform().split("-",1)[0]   #判断是那个操作系统,因为我的服务器是Linux的但我电脑是windows的,所以只设置了这两个系统的判断if  self.system_ ==  "Windows":  #对windows的文件格式进行设置self.filePath = (self.filePath + "\\") if self.filePath.rsplit("\\",1)[-1] else self.filePathelif self.system_ == "Linux":  #对Linux的文件格式进行设置self.filePath = (self.filePath + "/") if self.filePath.rsplit("/",1)[-1] else self.filePathself.fileInputPath = self.filePath + inputName   #拼接输入的路径self.fileOutPath = self.filePath + outName    #拼接输出的路径

2.设置判断文件是否是图片或视频

 @propertydef is_picture(self):picSuffixSet = {"BMP","GIF","JPEG","TIFF","PNG","SVG","PCX","WMF","EMF","LIC","EPS","TGA","JPG"}  #常用后缀,集合的搜索速度快,所以用集合而不用列表,还能做到去重,避免输入了重复的后缀名suffix = self.fileInputPath.rsplit(".",1)[-1].upper()if suffix in picSuffixSet:return Trueelse:return False@propertydef is_video(self):videoSuffixSet = {"WMV","ASF","ASX","RM","RMVB","MP4","3GP","MOV","M4V","AVI","DAT","MKV","FIV","VOB"}suffix = self.fileInputPath.rsplit(".",1)[-1].upper()if suffix in videoSuffixSet:return Trueelse:return False

3.对上传的图片进行压缩

import zlib  #压缩的库
import threading    #多线程
from PIL import Imagedef SavePic(self):fpsize = os.path.getsize(self.fileInputPath) / 1024  # 获得图片多少K   os.path.getsize(self.picPath)返回的是字节if fpsize >= 50.0:  # 是否大于50Kim = Image.open(self.fileInputPath)  # 打开图片imBytes = im.tobytes()  # 把图片转换成bytes流imBytes = zlib.compress(imBytes, 5)  # 对图像字节串进行压缩,第二个参数是压缩率有-1,0-9,按个人情况进行设置,我都试过了感觉没多大变化,所以随便设置了5im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes))  # 压缩成新的图片if self.outName:im2.save(self.fileOutPath)  #不覆盖原图return (self.fileOutPath,os.path.getsize(self.fileOutPath))else:im2.save(self.fileInputPath)    #覆盖原图return (self.fileInputPath,os.path.getsize(self.fileInputPath))else:return Truedef Compress_Picture(self):#异步保存打开下面的代码,注释同步保存的代码,我选用的是异步保存,因为如果图片太大用同步的话会阻塞程序的运行,按自己的情况去选择,也可以设置一个变量,然后用判断来看是否启动多线程保存thr = threading.Thread(target=self.SavePic)thr.start()#下面为同步保存# fpsize = os.path.getsize(self.fileInputPath) / 1024  # 获得图片多少K   os.path.getsize(self.picPath)返回的是字节# if fpsize >= 50.0:  # 是否大于50K#     im = Image.open(self.fileInputPath)  # 打开图片#     imBytes = im.tobytes()  # 把图片转换成bytes流#     imBytes = zlib.compress(imBytes, 5)  # 对图像字节串进行压缩#     im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes))  # 压缩成新的图片#     if self.outName:#         im2.save(self.fileOutPath)  # 不覆盖原图#         return (self.fileOutPath, os.path.getsize(self.fileOutPath) / 1024)#     else:#         im2.save(self.fileInputPath)  # 覆盖原图#         return (self.fileInputPath, os.path.getsize(self.fileInputPath) / 1024)# else:#     return True

4.对上传的视频进行压缩

import osdef SaveVideo(self):fpsize = os.path.getsize(self.fileInputPath) / 1024if fpsize >= 150.0: #大于150KB的视频需要压缩if self.outName:compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(self.fileInputPath,self.fileOutPath)isRun = os.system(compress)else:compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(self.fileInputPath, self.fileInputPath)isRun = os.system(compress)if isRun != 0:return (isRun,"没有安装ffmpeg")return Trueelse:return Truedef Compress_Video(self):# 异步保存打开下面的代码,注释同步保存的代码thr = threading.Thread(target=self.SaveVideo)thr.start()#下面为同步代码# fpsize = os.path.getsize(self.fileInputPath) / 1024# if fpsize >= 150.0:  # 大于150KB的视频需要压缩#     compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(#         self.fileInputPath, self.fileOutPath)#     isRun = os.system(compress)#     if isRun != 0:#         return (isRun, "没有安装ffmpeg")#     return True# else:#     return True

我这里使用了是ffmpeg对视频进行压缩,这个是一个非常好用的工具,Linux和windows都有,在Linux中可以使用apt install ffmpeg进行安装(我用的是Ubuntu的系统,所以使用apt进行安装,如果用的是Centos的用对应的yum进行安装就行了)

ffmpeg命令解释

ffmpeg -i 1.mp4 -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 147fss.mp4
  • -i 输入的视频文件
  • -r 每一秒的帧数,一秒10帧大概就是人眼的速度
  • -pix_fmt 设置视频颜色空间 yuv420p网络传输用的颜色空间 ffmpeg -pix_fmts可以查看有哪些颜色空间选择
  • -vcodec 软件编码器,libx264通用稳定
  • -preset 编码机预设 编码机预设越高占用CPU越大 有十个参数可选 ultrafast superfast veryfast(录制视频选用) faster fast medium(默认) slow slower veryslow(压制视频时一般选用) pacebo
  • -profile:v 压缩比的配置 越往左边压缩的越厉害,体积越小 baseline(实时通信领域一般选用,画面损失越大) Extended Main(流媒体选用) High(超清视频) High 10 High 4:2:2 High 4:4:4(Predictive)
  • -level:v 对编码机的规范和限制针对不通的使用场景来操作,也就是不同分辨率设置不同的值(这个我没有设置,因为这个要根据不同的分辨率进行设置的,具体要去官方文档查看)
  • -crf 码率控制模式 用于对画面有要求,对文件大小无关紧要的场景 0-51都可以选择 0为无损 一般设置18 - 28之间 大于28画面损失严重
  • -acodec 设置音频编码器

完整代码

import sys
import os
import zlib
import threading
import platform
from PIL import Imageclass Compress_Pic_or_Video(object):def __init__(self,filePath,inputName,outName=""):self.filePath = filePath  #文件地址self.inputName = inputName  #输入的文件名字self.outName = outName  #输出的文件名字self.system_ = platform.platform().split("-",1)[0]if  self.system_ ==  "Windows":self.filePath = (self.filePath + "\\") if self.filePath.rsplit("\\",1)[-1] else self.filePathelif self.system_ == "Linux":self.filePath = (self.filePath + "/") if self.filePath.rsplit("/",1)[-1] else self.filePathself.fileInputPath = self.filePath + inputNameself.fileOutPath = self.filePath + outName@propertydef is_picture(self):picSuffixSet = {"BMP","GIF","JPEG","TIFF","PNG","SVG","PCX","WMF","EMF","LIC","EPS","TGA","JPG"}suffix = self.fileInputPath.rsplit(".",1)[-1].upper()if suffix in picSuffixSet:return Trueelse:return False@propertydef is_video(self):videoSuffixSet = {"WMV","ASF","ASX","RM","RMVB","MP4","3GP","MOV","M4V","AVI","DAT","MKV","FIV","VOB"}suffix = self.fileInputPath.rsplit(".",1)[-1].upper()if suffix in videoSuffixSet:return Trueelse:return Falsedef SavePic(self):fpsize = os.path.getsize(self.fileInputPath) / 1024  # 获得图片多少K   os.path.getsize(self.picPath)返回的是字节if fpsize >= 50.0:  # 是否大于50Kim = Image.open(self.fileInputPath)  # 打开图片imBytes = im.tobytes()  # 把图片转换成bytes流imBytes = zlib.compress(imBytes, 5)  # 对图像字节串进行压缩im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes))  # 压缩成新的图片if self.outName:im2.save(self.fileOutPath)  #不覆盖原图return (self.fileOutPath,os.path.getsize(self.fileOutPath))else:im2.save(self.fileInputPath)    #覆盖原图return (self.fileInputPath,os.path.getsize(self.fileInputPath))else:return Truedef SaveVideo(self):fpsize = os.path.getsize(self.fileInputPath) / 1024if fpsize >= 150.0: #大于150KB的视频需要压缩if self.outName:compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(self.fileInputPath,self.fileOutPath)isRun = os.system(compress)else:compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(self.fileInputPath, self.fileInputPath)isRun = os.system(compress)if isRun != 0:return (isRun,"没有安装ffmpeg")return Trueelse:return Truedef Compress_Picture(self):#异步保存打开下面的代码,注释同步保存的代码thr = threading.Thread(target=self.SavePic)thr.start()#下面为同步保存# fpsize = os.path.getsize(self.fileInputPath) / 1024  # 获得图片多少K   os.path.getsize(self.picPath)返回的是字节# if fpsize >= 50.0:  # 是否大于50K#     im = Image.open(self.fileInputPath)  # 打开图片#     imBytes = im.tobytes()  # 把图片转换成bytes流#     imBytes = zlib.compress(imBytes, 5)  # 对图像字节串进行压缩#     im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes))  # 压缩成新的图片#     if self.outName:#         im2.save(self.fileOutPath)  # 不覆盖原图#         return (self.fileOutPath, os.path.getsize(self.fileOutPath) / 1024)#     else:#         im2.save(self.fileInputPath)  # 覆盖原图#         return (self.fileInputPath, os.path.getsize(self.fileInputPath) / 1024)# else:#     return Truedef Compress_Video(self):# 异步保存打开下面的代码,注释同步保存的代码thr = threading.Thread(target=self.SaveVideo)thr.start()#下面为同步代码# fpsize = os.path.getsize(self.fileInputPath) / 1024# if fpsize >= 150.0:  # 大于150KB的视频需要压缩#     compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(#         self.fileInputPath, self.fileOutPath)#     isRun = os.system(compress)#     if isRun != 0:#         return (isRun, "没有安装ffmpeg")#     return True# else:#     return Trueif __name__ == "__main__":b = sys.argv[1:]  #测试压缩savepic = Compress_Pic_or_Video(b[0],b[1],b[2])print(savepic.Compress_Picture())

测试情况

对图片进行压缩

左边为没压缩过的原图,右边是压缩过后的原图,两张图片像素都是一样的,两张图片用肉眼几乎分辨不出差别

对视频进行压缩

左边为未压缩过的原视频文件,右边为压缩过的视频文件,可见帧宽度与帧高度都没发生过改变,只是修改了数据速率,总比特率等的这些信息,源文件帧速率为每秒12帧,现在压缩成了每秒10帧,人眼是没办法分别出12帧与10帧的区别的,我测试过原视频和压缩后的视频观看上是没有却别的,声轨也听不出。

参考的文章

https://blog.csdn.net/oh5W6HinUg43JvRhhB/article/details/80850839

http://ffmpeg.org/documentation.html

python压缩图片和视频相关推荐

  1. python压缩图片--指定压缩大小且保真压缩

    代码核心思路 循环降低图片质量quality 直至图片质量大小符合目标质量后退出循环 pillow压缩失真严重 ''' pip install pillow ''' from io import By ...

  2. Python实现图片和视频的相互转换

    有时候我们需要把很多的图片合成视频,或者说自己写一个脚本去加快或者放慢视频:也有时候需要把视频裁剪成图片,进行后续操作.这篇文章就将为大家介绍如何通过Python实现图片和视频的相互转换,需要的可以参 ...

  3. python提取图片文字视频教学_Python学习第七天之爬虫的学习与使用(爬取文字、图片、 视频)...

    一.爬虫记得基本方法 1.1 爬虫概述 ​网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使 ...

  4. Python 将图片或者视频模糊化(附代码) | Python工具类

    目录 前言 环境依赖 代码 总结 前言 本文主要分享一个可以将图片或者视频模糊化的工具代码.技术路线主要是使用ffmpeg滤镜. 环境依赖 ffmpeg环境部署,直接参考我的另一篇文章:windows ...

  5. 教你用Python压缩图片

    质量.速度.廉价,选择其中两个 如果需要做图片识别那么必定需要大量的训练素材,我们通常使用爬虫来获取,python爬取bing图片,python爬取百度图片,但是怕取下来的图片大小不一,再进行训练之前 ...

  6. 【pngquant】使用Python压缩图片,降低网页加载时间

    更多内容请点击 我的博客 查看,欢迎来访. 用来做什么? 个人在写博客时,发现上传的图片如果很大,web访问第一次加载该图片就特别的慢. 可以考虑使用缩略图,浏览时显示缩略图,如果要看高清图,需点击图 ...

  7. python 压缩图片为指定大小

    转自:scipy笔记-scipy.misc.imresize用法(方便训练图像数据) from skimage.transform import resize # 压缩图片 def predict_m ...

  8. python cv 图片转视频

    视频编码 fourcc:全名Four-Character Codes,四字符代码,该编码由四个字符组成 cv2.VideoWriter_fourcc('M','J','P','G') cv2.Vide ...

  9. python --压缩图片不改变图片尺寸

    方法1 from PIL import Image import osdef compress_image(infile, outfile, quality=50):""" ...

  10. python提取图片文字视频教学_用Python提取视频中的图片

    小编自己码的通用型函数,支持各种常用视频格式,可满足常用需求,亲测效果和速度都不错. 想获取本文数据和完整代码的下载链接,请关注微信公众号"R语言和Python学堂",并回复发文日 ...

最新文章

  1. 【BIEE】数据透视表格第一列添加序号
  2. tcpmp 编译 源代码分析
  3. 浅析如何通过PHP类的反射来实现依赖注入
  4. 【紫书第十一章】图论模型与算法入门
  5. 编译错误:GL/glew.h, GL/glut.h, EGL/egl.h没有那个文件或目录
  6. 谈谈web上各种图片应用的优缺点
  7. Optisystem7中 matlab元件 使用
  8. 电子设计大赛-运算放大器
  9. gitlab设置项目组成员权限
  10. Java面试单点登录_单点登录面试题
  11. vue-router 基本使用
  12. 医学信息化管理与建设
  13. 内存管理基本原理及非ARC环境使用小心得
  14. 网络攻防 横向移动_网络安全101的数据分析:检测横向移动
  15. 【玩转c++】多态深度刨析
  16. 软考高级-信息系统管理师之项目管理基础(最新版)
  17. Pairs(暴力,超详细简单)
  18. 利用建造者(Builder)模式构建 Java 对象
  19. 初中计算机基础考试试题及答案,计算机基础考试试题及答案(三)
  20. Python使用ffmpeg合成视频、音频

热门文章

  1. 网络系统设计综合布线方案
  2. 微型计算机外观分为,2015计算机应用基础单选练习题1.1
  3. 广告终结者chinalist-easylist语法规则
  4. 使用广告终结者屏蔽页面的任意部分
  5. 码农小汪-Hibernate学习6-hibernate中Annocation修饰属性
  6. lomboz eclipse怎么连接oracle10,Lomboz插件的安装与配置[Eclipse 3.0,3.1.x与3.2.x版本]第一部分...
  7. Win10获取管理员权限
  8. Picasa2图片查找浏览工具
  9. CSS布局控制--盒子模型
  10. C#初学者教程系列3:Hello World:第一个控制台应用程序