坦白地说,我是那个花了两天两夜把一张1M的图片优化到100kb的家伙——王小二!
自从一篇报道登上热搜后,我几乎抑郁了,每天要吃50片安眠药才能睡着。
网上曝光的关于一码通的消息,我就不澄清真假了。说说我是怎么把图片从1M优化到100kb的故事吧。
是的,因为系统组规模和访问规模的特殊性,每一行代码,每一张图片,每一份技术文档都是反复审批,优化再优化,精益求精。为了保证系统更高效的运行,我们把一张图片从1MB压缩到500KB,然后从500KB优化到100KB。
这种工作在外人看来就像悄悄塞一封情书给我学妹让她做我女朋友一样简单。
但殊不知,它包含了极高的技术含量!
不信我给你普及一下。
一、图像压缩图像压缩是数据压缩技术在数字图像中的应用。目的是减少图像数据中的冗余信息,以便以更有效的格式存储和传输数据。
图像压缩可以是有损数据压缩或无损数据压缩。
最近怎么样?
是不是感觉图像压缩技术没有你想象的那么简单?
二、Java数字图像处理作为这个“20多万外包项目”的“主要开发者”,我在这里给大家介绍一下Java数字图像处理技术。一开始我用它来处理图片。
数字图像处理是利用计算机对图像进行去噪、增强、恢复、分割和特征提取的方法和技术。
输入是图像信号,然后经过DIP的有效算法处理,输出是数字信号。
为了压缩图像,我们需要读取图像并将其转换为BufferedImage对象。BufferedImage是Image类的一个子类,描述了一个可访问的图像数据缓冲区,由ColorModel和Raster的图像数据组成。
废话不多说。直接实战吧!
三、图像压缩实战我正好本地有一张以前用过的封面图,距离1M只有236 KB,可以用来测试。
这就涉及到ImageIO类,它是一个静态类,提供了一系列读写图像的方法,也可以简单的对图像进行编码和解码。
例如,通过ImageIO.read(),可以将图像读取到BufferedImage对象:
文件输入=新文件(& # 34;ceshi.jpg & # 34); buffered image image = imageio . read(input);比如通过imageio。getImageWritersbyformatname(),可以返回一个迭代器,它包含按指定格式编码图像的imagewriter。
迭代器& ltImageWriter & gtwriters = imageio . getimagewritersbyformatname(& # 34;jpg & # 34); ImageWriter writer =(image writer)writers . next();例如,可以通过imageio . createimageoutputstream()创建一个图像的输出流对象,然后通过ImageWriter.setOutput()将其设置为输出流。
File compressedImageFile =新文件(& # 34;bbcompress.jpg & # 34); output stream OS = new file output stream(compressed image file); ImageOutputStream IOs = imageio . createimageoutputstream(OS); writer . set output(IOs);然后,可以配置ImageWriter的一些参数,比如压缩模式,压缩质量等等。
ImageWriteParam param = writer . getdefaultwriteparam(); param . set compression mode(ImageWriteParam。模式_显式); param . setcompressionquality(0.01 f);有四种压缩模式。MODE_EXPLICIT就是其中之一,这意味着ImageWriter可以根据后续集合的附加信息进行平铺和压缩,比如下一个setCompressionQuality()方法。
setCompressionQuality()方法的参数是一个介于0和1之间的数字,0.0表示最大压缩,1.0表示保证图像质量很重要。对于有损压缩方案,压缩质量应控制文件大小和图像质量之间的权衡(例如,在写JPEG图像时选择量化表)。对于无损方案,压缩质量可用于控制文件大小和执行压缩所需时间之间的权衡(例如,通过优化行过滤器和在写入PNG图像时设置ZLIB压缩级别)。
整体代码如下:
public class Demo { public static void main(String[]args){ try { File input = new File(& # 34;ceshi.jpg & # 34); buffered image image = imageio . read(input); 迭代器& ltImageWriter & gtwriters = imageio . getimagewritersbyformatname(& # 34;jpg & # 34); ImageWriter writer =(image writer)writers . next(); File compressed image File = new File(& # 34;bbcompress.jpg & # 34); output stream OS = new file output stream(compressed image file); ImageOutputStream IOs = imageio . createimageoutputstream(OS); writer . set output(IOs); ImageWriteParam param = writer . getdefaultwriteparam(); param . set compression mode(ImageWriteParam。模式_显式); param . setcompressionquality(0.01 f); writer.write(null,new IIOImage(image,null,null),param); OS . close(); IOs . close(); writer . dispose(); } catch(io exception e){ e . printstacktrace(); } } }执行压缩后,您可以看到图片大小减少到19 KB:
可以看出,当品质因子为0.01f时,画面已经有些失真,可以适当提高品质因子,比如0.5f我们再来看看。
画质明显提升,但大小依然只有64 KB,压缩效果依然值得信赖。
四、其他开源库接下来推荐一些可以轻松集成到项目中的图像处理库。都是免费的。
1)ImageJ,用Java编写,可以对图像进行编辑、分析、处理、保存和打印。
2)Apache Commons Imaging,一个读写各种图像格式的库,包含图像信息的快速分析(如大小、颜色、空房间、ICC配置文件等)。)和元数据。
3)ImageMagick可以读写100多种格式的图像,包括DPX、EXR、GIF、JPEG、JPEG-2000、PDF、PNG、Postscript、SVG和TIFF。您还可以调整大小,翻转,镜像,旋转,扭曲,剪切和变换图像,调整图像颜色和应用各种特殊效果,包括绘制文本,线条,多边形,椭圆和贝塞尔曲线。
BSD许可证颁发的OpenCV,可以免费学习和使用,提供包括C/C++、Python、Java等主流编程语言的接口。Opencv是专门为计算效率设计的,强调实时应用,可以充分发挥多核处理器的优势。
这里以OpenCV为例演示图像压缩。当然,OpenCV用来压缩图像是典型的矫枉过正。
第一步是将OpenCV添加到我们的项目中,以Maven为例。
& lt依赖性& gt & lt;groupId & gtorg.openpnp & lt/groupId & gt; & lt;artifactId & gtopencv & lt/artifact id & gt; & lt;版本& gt4 . 5 . 1-2 & lt;/version & gt; & lt;/dependency & gt;第二,如果要使用OpenCV,需要先初始化。
opencv . load shared();第三步,使用OpenCV读取图片。
mat src = img codecs . im read(image path);第四,用OpenCV压缩图片。
Mato fint dst image = new Mato fint(img codecs。IMWRITE_JPEG_QUALITY,1); Imgcodecs。im write(& # 34;resized _ image.jpg & # 34、sourceImage、dst image);MatOfInt的构造参数是一个可变参数。第一个参数IMWRITE_JPEG_QUALITY的意思是改变画质。第二个参数是品质因子,它是1-100。价值越高,质量越高。
执行代码后得到的图片如下:
借此机会比较一下OpenCV和jdk native API在压缩图像上所花费的时间。
这是我机器的配置。早年买的顶级iMac也是我的主力机。一开始只有16 GB内存,后来加了16 GB内存条。但最近半年,电脑突然死机重启的频率明显增加。不知道是大苏尔操作系统有问题还是电脑硬件老旧。
结果如下:
OpencvCompress完成,耗时:1070 jdkCompress完成,耗时:322压缩后的图片大小差不多,都是19 KB,质量因子最低。
经过以上的技术分析,相信大家都明白了,把1M的画面优化到100kb真的不容易。。。。
100KB不算小吗?只有原来的1/10。
要知道,我加班两天两夜没睡觉。
最后,我在电脑前睡着了。
没想到Harrah直接把电脑短路了,把我从梦中吓醒了!
资料来源:https://www.cnblogs.com/qing-gee/p/15980369.html