引言

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

1.新建一个类

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

import platform

class 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.filePath

elif self.system_ == "Linux":#对Linux的文件格式进行设置

self.filePath = (self.filePath + "/") if self.filePath.rsplit("/",1)[-1] else self.filePath

self.fileInputPath = self.filePath + inputName#拼接输入的路径

self.fileOutPath = self.filePath + outName#拼接输出的路径

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

@property

def 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 True

else:

return False

@property

def 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 True

else:

return False

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

import zlib#压缩的库

import threading#多线程

from PIL import Image

def SavePic(self):

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) # 对图像字节串进行压缩,第二个参数是压缩率有-1,0-9,按个人情况进行设置,我都试过了感觉没多大变化,所以随便设置了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 True

def 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 os

def SaveVideo(self):

fpsize = os.path.getsize(self.fileInputPath) / 1024

if 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 True

else:

return True

def 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 Image

class 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.filePath

elif self.system_ == "Linux":

self.filePath = (self.filePath + "/") if self.filePath.rsplit("/",1)[-1] else self.filePath

self.fileInputPath = self.filePath + inputName

self.fileOutPath = self.filePath + outName

@property

def 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 True

else:

return False

@property

def 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 True

else:

return False

def SavePic(self):

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))

else:

im2.save(self.fileInputPath) #覆盖原图

return (self.fileInputPath,os.path.getsize(self.fileInputPath))

else:

return True

def SaveVideo(self):

fpsize = os.path.getsize(self.fileInputPath) / 1024

if 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 True

else:

return True

def 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

def 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

if __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帧的区别的,我测试过原视频和压缩后的视频观看上是没有却别的,声轨也听不出。

参考的文章

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

  1. python读视频文件_python读取和保存视频文件

    如何用python实现视频关键帧提取并保存为图片?也许你会觉得对小编多做一点事你会觉得你很爽,可是在小编看来这是不屑的 import cv2vc = cv2.VideoCapture('Test.av ...

  2. python压缩视频文件_python+压缩视频教程

    python+压缩视频教程内容摘要 python+压缩视频教程做饭的比较少.python做exe开发教程,可省却昂贵的租金,可设单世间.双世间.4世间.8世间,可设单人间.双人间.4人间.8人间,可去 ...

  3. python解压文件_Python压缩和解压缩文件(zip/unzip)详解

    通过zipfile模块实现对文件.文件夹的zip压缩和解压 #打包成zip文件 import zipfile f = zipfile.ZipFile('archive.zip','w',zipfile ...

  4. python读取lmdb文件_python将图片转成lmdb格式

    about 本文参考了 在开始前... 先说说几处坑: 虽然安装了caffe,但是 import lmdb 出现error.StackOverflow上的同学们讨论说,要装一个lmdb 2 于是开始装 ...

  5. python压缩视频文件_python使用zlib库压缩图片,使用ffmpeg压缩视频

    # ffmpeg -i 1.mp4 -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline -crf 2 ...

  6. 压缩视频文件怎么压缩最小?

    压缩视频文件怎么压缩最小?相信每个小伙伴都和我一样,希望电脑里每个文件的体积都能小一点,这样才能不占用更多的存储空间,文件上起来也方便,发送给别人的时候也不会有限时,一会就能发送成功.但往往总是事与愿 ...

  7. 如何将视频文件在线压缩,压缩的方法

    视频我们都知道吧,用各种播放器播放的电视剧叫视频,手机拍摄的短片也叫视频,可是我们每天都要浏览很多的视频,也会有很多的视频保存在我们的电脑和手机之中,而这些视频我也不想删除,毕竟有的很正能量,有的很珍 ...

  8. 压缩 Excel 文件中的图片

    压缩 Excel 文件中的图片 1. 图片工具 -> 格式 打开 Excel 文件,选中任一图片.查看图片工具 -> 格式. 2. 压缩图片 不选择 仅用于所选图片,就是默认压缩所有图片. ...

  9. 手机视频文件怎么压缩变小

    手机视频文件怎么压缩变小?压缩手机视频的方法还是有的,下面小编介绍一个视频压缩的简单方法,有需要的小伙伴可以来围观哦!希望能够帮到你们. 使用压缩软件进行压缩 1:打开电脑上安装的视频压缩软件,点击页 ...

  10. Silverlight读取Zip文件中的图片与视频

    置顶声明:本文原创版权归 博客园 Ringgo.Yao 所有,如有转载,请按如下方式详细标明原文作者及出处,以示尊重!! 原创作者:Ringgo.Yao 原文出处:Silverlight读取Zip文件 ...

最新文章

  1. 康复治疗学可以考计算机吗,【大揭秘】2018“人机对话”康复医学治疗技术专业技术资格考试...
  2. Java:Object.hashCode()和System.identityHashCode()的区别
  3. BootStrap 智能表单系列 五 表单依赖插件处理
  4. linux+平均磁盘请求数量_SUSE LINUX下磁盘IO性能监测分析
  5. 机器人学习--粒子滤波/MCL定位的理论基础(先验知识)
  6. 请教SQL对日期格式化的写法
  7. 微信果断出手 将封禁拼团砍价链接,网友:终于可以清静了
  8. skimage 图像读取显示
  9. jsp+aJax 登陆成功
  10. btr如何修改服务器手机版我的世界,我的世界btr编辑器
  11. Modbus通讯协议详解与RTU通信实例演示
  12. 数学建模之回归分析加例题详解(MATLAB实现)
  13. bp神经网络算法的优缺点,bp神经网络缺点及克服
  14. 消防信号二总线有没电压_消防的电源总线和二总线的区别,二总线是不是信号线......
  15. 苹果进入多事之秋,电池门禁售门病魔缠身
  16. 计算机网络图标不见了,电脑网络图标不见了怎么恢复
  17. JDBDUitl代码记录
  18. 201771010101 白玛次仁 《2018面向对象程序设计(Java)》第十周学习总结
  19. GIF动图拆分为多个静态图片
  20. 比JMeter还轻量的压力测试工具是谁?Siege

热门文章

  1. 试试H3C Comware Platform Software Version 5.20
  2. php聊天功能界面,php实现聊天室功能完整代码
  3. Ubuntu20+TendaU12驱动离线安装
  4. java 多线程面试题及答案
  5. 快速上手python websockets
  6. jsZip将多个文件压缩成一个压缩包
  7. 把 14 亿中国人都拉到一个微信群,在技术上能实现吗?
  8. [python]excel试题转为json,并生成
  9. 视频编码格式 封装格式
  10. 淘宝婴儿商品销量分析