使用 opencv 将图片压缩到指定文件尺寸
前言
图片压缩应用很广泛,如生成缩略图等。前期我在进行图片处理的过程中碰到了一个问题,就是如何将图片压缩到指定尺寸,此处尺寸指的是生成图片文件的大小。
我使用 opencv 进行图片处理,于是想着直接使用 opencv 进行图片压缩处理, opencv 本身包含了压缩到指定像素大小的方法,奈何寻找了很多方法均不能压缩到指定文件尺寸,于是自己在思考后写出了此方法。本文使用python语言。
一、 opencv 常规使用
opencv 无需多言,做过图片处理的人应该都知道此类库,下面我介绍一些常用方法。
1.1 安装 opencv
首先安装 python ,建议 python3 ,然后执行
:
pip install opencv-python
1.2 读取图片
首先引入 opencv 包:
import cv2 as cv
而后读取图片:
image = cv.imread(path)
其中 path 为图片路径, image 为图片数据,是一个 numpy.ndarray 对象,其实就是一个多维数组。目前 opencv 支持几乎所有格式的图片(参考 http://blog.csdn.net/mars_xiaolei/article/details/78890971)。
1.3 保存图片
代码:
cv.imwrite(path, image)
其中 path 为保存的文件路径, image 为读取或者处理过的图片数据, opencv 根据保存文件的后缀名来写不同格式的图片数据,所以后缀名一定要写正确。
二、图片压缩
2.1 常规压缩
opencv 支持常规压缩,可以将图片压缩到指定的像素尺寸或者按比例缩放。
- 压缩到指定的像素尺寸:
new_image = cv.resize(image, size)
其中 size 是一个二维元组,表示压缩后图片的宽高。
- 按比例缩放:
new_image = cv.resize(image, None, fx, fy)
其中 fx , fy 表示图片在宽和高方向的压缩了比例。
2.2 压缩到指定文档大小
有了上面的基础我们来分析一下如何实现压缩到指定文档大小。
首先我们要读取原始文档的大小,算出原始文档大小和压缩目标值的比例,由于我们要实现的是宽高等比例压缩,于是将其开根号即表示在单边的压缩比例,调用 2.1 节中的按比例压缩。理论上一次就能达到效果,但是由于图片本身存在压缩,所以可能一次无法达到预期,只要对压缩后的图片重复此步骤,直到达到预期即可。
2.2.1 读取文档尺寸
def get_doc_size(path):
try:
size = os.path.getsize(path)
return get_mb_size(size)
except Exception as err:
print(err)
def get_mb_size(bytes):
bytes = float(bytes)
mb = bytes / 1024 / 1024
return mb
get_doc_size 函数返回图片的文档大小,单位为 MB 。
2.2.2 删除文件
def delete_file(path):
if file_exist(path):
os.remove(path)
else:
print('no such file:%s' % path)
def file_exist(path):
return os.path.exists(path)
由于我们需要删除压缩过程中产生的中间文件,所以需要调用 delete_file 方法删除之。
2.2.3 压缩
size = get_doc_size(path)
delete_file(resize_path)
while size > filesize:
rate = math.ceil((size / filesize) * 10) / 10 + 0.1
rate = math.sqrt(rate)
rate = 1.0 / rate
if file_exist(resize_path):
resize_rate(resize_path, resize_path, rate, rate)
else:
resize_rate(path, resize_path, rate, rate)
size = get_doc_size(resize_path)
其中 filesize 表示压缩目标值, path 表示原始文件路径, resize_path 表示压缩后存放路径, resize_rate 表示上述按比例压缩方法,定义如下:
def resize_rate(path, resize_path, fx, fy):
image = read_image(path)
im_resize = cv.resize(image, None, fx=fx, fy=fy)
delete_file(resize_path)
save_image(resize_path, im_resize)
def save_image(path, image):
cv.imwrite(path, image)
def read_image(path):
return cv.imread(path)
当然此处为了效果更好,我做了一些优化。
首先在获取压缩比例的时候我做了下述操作:
rate = math.ceil((size / filesize) * 10) / 10 + 0.1
理论情况应当是直接返回 size / filesize 即可,但是在实际测试过程中为了加速收敛,我采用上述方式,将一个小数先乘以 10 对其向上取整,这样就表示精度保留到原始数值小数后 1 位,即如果是 3.14 将得到 32 ,而后将此结果再除以 10 , 即得到 3.2 ,所以最终结果就是对小数后第二位进行向上进位,最后结果又加了 0.1 以更快速的收敛,当然你也可以去掉。
实际测试发现,一般重复执行两次即可得到理想的压缩效果,并且结果值与理想压缩尺寸相差无几。
三、结论
本文简单介绍了如何使用 opencv 将图片压缩到指定文件尺寸,当然你也可以选择其他文件处理类库而不是 opencv ,这个完全可以根据用户自己的兴趣而来,并且也可以优化最终的循环算法,以达到更佳的效果,或者更快的收敛。
使用 opencv 将图片压缩到指定文件尺寸的更多相关文章
- iOS学习——图片压缩到指定大小以内
一.图片压缩简述 在我们开发过程中,有可能会遇到拍照.或者从相册中选择图片,要么单选或者多选,然后上传图片到服务器,一般情况下一张图片可能3-4M,如果类似微信朋友圈上传9张图片大约是 35M左右,如 ...
- [Android算法] bitmap 将图片压缩到指定的大小
Bitmap压缩到指定大小: private void imageZoom() {//图片允许最大空间 单位:KBdouble maxSize =400.00;//将bitmap放至数组中,意在bit ...
- iOS开发探索-图片压缩处理
介绍: 压: 指文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降.缩: 指文件的尺寸变小,也就是像素数减少,而长宽尺寸变小,文件体积同样会减小. 应用: 在实际开发中,我们经常会对图片进行 ...
- C# 图片超过指定大小将压缩到指定大小不失真
using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;us ...
- Bitmap压缩到指定尺寸大小,获取圆角、圆形图片
/** * 使用Matrix将Bitmap压缩到指定大小 * @param bitmap * @param w * @param h * @return */ public static Bitmap ...
- 【问题帖】压缩图片大小至指定Kb以下
像PS,QQ影像等都有该功能,将图片大小压缩至指定kb以下. 我也来山寨一把,到目前为止,控制图片的大小,平时的解决方案通过分辨率和质量来控制的. 假定最后压缩的大小是100kb,那么在保证不大于10 ...
- java图片压缩工具类(指定压缩大小)
1:先导入依赖 <!--thumbnailator图片处理--> <dependency> <groupId>net.coobird</groupId> ...
- iOS 图片按比例压缩,指定大小压缩
使用系统方法UIImageJPEGRepresentation(UIimage *image,CGFloat quality)进行图片质量压缩,暂且叫参数quality为压缩比吧,取值范围为0-1. ...
- 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)
涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...
随机推荐
- JDBC学习笔记(三)
获取数据库的元信息metadata,里面有数据库特性的描述信息,如是否支持事务,是否支持批处理等. Connection conn = DriverManager.getConnection(url, ...
- json和xml的两者区别
服务器端返回给客户端的数据一般都是JSON格式,JSON数据以键值的形式保存,数据之间以逗号分隔,{}表示对象,[]表示数组.JSON数据解析方案有四种,JSONKit,SBJson,TouchJso ...
- 如何使用 Bootstrap 搭建更合理的 HTML 结构
前言 Bootstrap 的成功不仅在于其简单易用,更在于其样式的规范性以及 HTML 结构的合理性.但是很多人在使用 Bootstrap 时只是依照文档盲目的复制黏贴,并没有仔细考虑每个类的用处,也 ...
- CSS3及JS媒体查询教程
CSS3媒体查询: 语法: <media_query_list>:<media_query>[,<media_query>] <media_query> ...
- R语言-广义线性模型
使用场景:结果变量是类别型,二值变量和多分类变量,不满足正态分布 结果变量是计数型,并且他们的均值和方差都是相关的 解决方法:使用广义线性模型,它包含费正太因变量的分析 1.Logistics回归( ...
- Hive metastore表结构设计分析
今天总结下,Hive metastore的结构设计.什么是metadata呢,对于它的描述,可以理解为数据的数据,主要是描述数据的属性的信息.它是用来支持如存储位置.历史数据.资源查找.文件记录等功能 ...
- 自定义状态栏的颜色及navigation的title颜色
1.在info.plist中添加View controller-based status bar appearance,值为NO 2.在设置状态栏的地方添加代码 [[UIApplication sha ...
- C# 使用AngleSharp 爬虫图片
AngleSharp 简介 AngleSharp是基于.NET(C#)开发的专门解析HTML源码的DLL组件.根据HTML的DOM结构操作HTML,整个DOM已传输到逻辑类结构中.这种结构可以更好的操 ...
- js内存泄露的原因
1.意外的全局变量 function fun(){ a=19//全局变量 console.log(a) } 2.未及时清理计时器或者回调函数 //记得及时清理定时器 var intervalId=se ...
- C#委托与事件--后续补充
委托.事件补充 针对昨天文章 委托:让方法可以跟简单对象一样作为参数进行传递,也就是将方法作为参数进行封装. 方法:本质就是代码段 其实也好理解,目的就是为了封装,多态,既然简单对象如int i可以做 ...