当前位置:首页 » 网页前端 » webjs图片压缩
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

webjs图片压缩

发布时间: 2022-12-21 15:52:35

1. Web图片的常见压缩格式

本文简单介绍几种常见的图片格式,对比压缩率和质量。

PNG是一种非常流行的无损压缩格式,所有的浏览器都支持这种格式。 它提供了卓越的图像质量,但是通常来说压缩率较低。

本文将使用PNG图片作为基准,对比其他有损格式压缩,检查图片质量并对图片质量进行评分。

虽然PNG格式老,体积大,但它仍然在网络上占有一席之地,尤其是在一些对画质要求很高的场景。同时对于边缘非常锐利的图像(例如包含文本的图像),也建议选择PNG。 对此类图片,PNG压缩与其他格式(包括有损压缩)相比,文本图像使用PNG实际上具有更高的压缩率,并且具有更好的质量优势。

PNG有两种模式:24位或8位颜色深度。 前者用于表示照片,后者用于文本图像,单色照片或Logo图像。 

BMP只是一个图像的容器,不提供压缩。 这是一种格式,主要在图像处理中使用,譬如说Windows里面的调色板。

BMP的尺寸很容易计算,譬如说分辨率是1920x1080p的RGB图像,整个的存储空间大约就是1920 x 1080 x 3 ,大约5MB。可以看得出来,BMP文件的大小明显大于压缩格式,包括PNG。通常来说,没有特殊情况,不应在网站上使用BMP图片,不过实际情况下网站上还是有很多BMP图像的。

一般来说,如果想要文件更小,就需要花费更多的处理时间来对文件进行编码,而解码时间一般来说相差不大。

回顾一下,BMP图像质量很好,浏览器支持广泛,但是文件尺寸却非常大。

GIF作为动画格式非常流行,不管是微信里面转发的动图表情,还是网站上的动图,都随处可见,所有的浏览器也都支持GIF图像。

GIF具有无损压缩和有损压缩的混合特性。像素表示形式是无损的,但是颜色深度限制为每个像素8位(即每个图像转换为256色,原始的图像如果是RGB格式的,每个像素实际上使用24位来表示的)。这意味着文件将包含较少的颜色(每个文件最多包含256种不同的颜色),但文件体积更小。 这是24位PNG和8位GIF之间的色彩表示的比较。

可以明显看到GIF图像有轮廓效应,这是因为GIF无法表示丰富的色彩。

GIF不适合表示照片或任何其他内容丰富的图片。但是它们对于简单的徽标,图标等很有用,因为这些图片颜色不多,而且纯色居多。根据我的经验,与GIF相比,8位PNG生成的文件更小,所以对于静态图片而言,建议采用8bit PNG。

SVG格式比较特殊,与其他格式有很大不同。 SVG图像存储的是几何形状,而不是每个像素的值。 它的主要优势是可以无限放大而不会造成质量损失,具体可以看下图的对比:

SVG文件类型主要用于徽标,但也用于几何形状的图像。 这种文件的主要缺点是:

对于徽标等小图片,文件大小通常比PNG或WebP大,尤其对于形状复杂,不规则的logo。在大多数情况下,无法将图片有效地转换为SVG(有一些工具说可以做到这一点,但效果并不理想)。

不论视图大小如何,SVG文件的图像质量都很高。 所有现代浏览器都支持它。

JPEG是网络图像的王者。 网络上绝大多数的图像以JPEG格式存储,具体的份额可以参考下图:

什么使JPEG如此流行? JPEG文件对于绝大多数文件通常都很小。 它的压缩使用有损算法,通过牺牲人眼不太敏感的区域的质量来最小化大小。

这种方法可显着减小尺寸,通常不会出现明显的变形。 我们可以对比下JUNO探测器拍摄的这张木星照片。

原始PNG照片(2MB)   JPEG最好的质量(1MB) JPEG默认的质量

使用JPEG压缩,我们可以大幅度缩小尺寸(超过90%),而不会造成质量损失。 当我们放大这些图片时,质量上也没有很大的损失。

JPEG并不是对于所有图像都很管用,如前面介绍PNG时所说的,对于具有锐利边缘和颜色比较少的图像,JPEG并不是非常管用。常见的例子就是包含文字的图片,另一个是徽标:

在这幅图片里面,JPEG图像大约2KB(是PNG文件的两倍),同时放大来看,JPEG对于边缘的表示并不理想,同时颜色也有失真。失真非常明显,即使在图像的未缩放部分上也清晰可见。

JPEG有两种格式,一种是Baseline JPEG,一种是Progressive JPEG.

两者之间的视觉差异是加载图像的方式。 随着数据的到达,Baseline从上到下加载图像。 Progressive以非常低的质量一次打印整个图像,并且随着数据的到达,图像得到了改善。 这里是展示差异的动画:

JPEG之外的世界– WebP

JPEG压缩可以很好地减小文件大小,不过JPG已经过时了。 如您所知,IT开发的几年就像外面的一个世纪一样。 

最近几年已经有更新的编码方法(例如mozJPG),但核心思想保持不变。

同时还有其他的格式在图像质量和文件大小方面都更好(BPG, JPEG 2000, JPEG XR),但因为某些格式受专利保护,无法在网络上广泛使用。

幸运的是,有一个可供公众使用的WebP。 目前,这种格式由Google开发并开源,并采用无损和有损压缩以最小化文件大小。许多现代浏览器都支持它,但覆盖范围仍然存在差距。 截至2018年8月,全球将近75%的用户使用支持WebP图像的浏览器浏览Web。 WebP图像的文件大小和质量看起来很有希望。除了压缩性能出色外,它的最大优势还在于多功能性。 它可以有损和无损压缩,具有特定的颜色深度,透明度和动画效果。 它在所有这些领域中也表现出色。

简单总结下,对于静态图片几种格式的对比如下:

下一篇介绍下常见的动态格式有哪些。

2. 如何实现JS中图片压缩方法

1.这个用PS转换成JPG或者GIF或png比较大小选用。

3. 怎么用JavaScript在线压缩图片

主要用了两个html5的 API,一个file,一个canvas,压缩主要使用cnavas做的,file是读取文件,之后把压缩好的照片放入内存,最后内存转入表单下img.src,随着表单提交。
照片是自己用单反拍的,5M多,压缩下面3张分别是600多kb,400多kb,300kb的最后那张失真度很大了,压缩效率蛮高的。

<!DOCTYPE html>
<html><head> <meta charset="utf-8"/> <title>File API Test</title> <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script> <script type="text/javascript" src="js/JIC.js"></script> <style> #test{ display: none; } </style></head><body><input type="file" id="fileImg" ><form> <img src="" id="test" alt=""></form><script> function handleFileSelect (evt) { // var filebtn = document.getElementById(id); // console.log(filebtn); // var files = filebtn.target.files; // console.log(filebtn.target); // console.log(files); var files = evt.target.files; for (var i = 0, f; f = files[i]; i++) { // Only process image files. if (!f.type.match('image.*')) { continue; } var reader = new FileReader(); // Closure to capture the file information. reader.onload = (function(theFile) { return function(e) { // Render thumbnail. // console.log(evt.target.files[0]); // console.log(e.target); console.log(e.target.result); var i = document.getElementById("test"); i.src = event.target.result; console.log($(i).width()); console.log($(i).height()); $(i).css('width',$(i).width()/10+'px'); //$(i).css('height',$(i).height()/10+'px'); console.log($(i).width()); console.log($(i).height()); var quality = 50; i.src = jic.compress(i,quality).src; console.log(i.src); i.style.display = "block"; }; })(f); // Read in the image file as a data URL. reader.readAsDataURL(f); } } document.getElementById('fileImg').addEventListener('change', handleFileSelect, false);</script></body></html>

var jic = { /** * Receives an Image Object (can be JPG OR PNG) and returns a new Image Object compressed * @param {Image} source_img_obj The source Image Object * @param {Integer} quality The output quality of Image Object * @return {Image} result_image_obj The compressed Image Object */ compress: function(source_img_obj, quality, output_format){ var mime_type = "image/jpeg"; if(output_format!=undefined && output_format=="png"){ mime_type = "image/png"; } var cvs = document.createElement('canvas'); //naturalWidth真实图片的宽度 cvs.width = source_img_obj.naturalWidth; cvs.height = source_img_obj.naturalHeight; var ctx = cvs.getContext("2d").drawImage(source_img_obj, 0, 0); var newImageData = cvs.toDataURL(mime_type, quality/100); var result_image_obj = new Image(); result_image_obj.src = newImageData; return result_image_obj; }, function ****(***)

4. WEB保存图片被压缩了 怎么处理

压缩的是图片质量,不是图片尺寸。商品详情页不需要特别高的质量要求,这块数字默认是不用更改的。如果实在想存高质量的图片,可以导出为tif格式。

5. js压缩图片最低能压缩多百分之多少

js最低能压缩百分之一, 最大可放大至原来的5倍 2.👐最小可缩放至原来的百分之10 第二种保持图片宽度长度不变改变图片质量,但不能用于放大图片 最小可压缩至原图的百分之一

6. 怎样在客户端 利用js 压缩图片 大小,然后上传至服务器比如2M压缩成几十KB

无法实现,js没有权限去修改本地文件的,只能是将大图上传到服务器后再压缩

7. web前端 图片压缩

我的理解应该是生成图片的时候,在不影响图片质量的情况下,尽量用体积小的格式,比如在不透明的情况下尽量把图片保存成png格式。
在css中有一种技术叫做图片精灵,就是把一些背景图做成集合的形式。图片只需加载一次。
最后网上好像是有插件(浏览器也有插件)可以对图片进行压缩处理。

8. js压缩图片 到固定像素以内,500k为例

本文旨在探究js压缩图片的两种方式: 改变图片长宽 改变图片质量 ,和结合了以上两者的 最终方案

首先,阅读本文需要知道canvas的两个方法

这两个方法具体的说明可以在MDN上查看,关于图片压缩,也有很多现成的博客可以直接用。但是那些博客都有个问题,并没有关心之后图片的压缩质量。
我试着用一个现成的例子去跑了一下,一个1.7M的图片压缩到了23k,堪称像素级毁灭性破坏。

假如一张大图可能包含着很多文字等关键信息,必须上传之后使用方能清晰辨认。所以要压缩之后质量尽可能接近500k的。500k像素以内,就是若一张图宽度为1024,则高度不能超过500。因为图片有其他的信息,也是要占大小的。即不得大于 1024*500

所以,根据需求,上传图片不能超过500k的情况下尽可能保留图片的清晰度。当然如果可以的情况下用上面提到的 canvas.toDataURL 设置压缩程度为0.9,0.8试试看,图片质量可以接受,大小会有大幅度的缩小。

如果不压缩,靠调整图片长宽去控制上传大小呢?
原理很简单,就是靠不断地缩小限定的最大宽高,直到最终长宽的积小于规定的大小。
这种方法有可能最后得出的图片的大小会略大于规定大小,原因上文也提到过了,如果想使用这种方法,可自行再调整一下。

上面的方法有个问题,就是改变了图片的原始长宽。如果一个图的长宽足够大,压缩图片质量,糊一点但是内容看得清也是ok的嘛。所以,跟上面同理,我们可以不断调整图片的质量设定直到大小合适,那么,如何在图片上传之前知道图片的大小呢?
首先,需要知道的一点是,压缩之后拿到的base64字符串会转成blob对象,然后传给服务端。
可以查阅文档,blob对象有个属性是size

这个size就是上传之后实际的文件大小。
参照上面的思路,可以每次改变 canvas.toDataURL('image/' + fileType, level); level的值,去调整压缩图片质量,然后用blob对象的size去验证是否满足500k以内的需求。
关于 canvas.toDataURL 的level到底是怎么计算的,MDN文档里也没说,写了个循环一次减少0.1的level压缩了几个图片

用加减乘除算了一下,没找到规律,数学不好放弃了(这个东西好像也不是能观察出来的,看结果跟初始大小没啥关系)。
这里要注意的是,有可能遇到超大图片,0.1的level可能不足以压缩到500k,所以小于0.1的时候,改变level递减的差值继续压缩下去

在开始接收到图片的时候给一个loading增加用户的耐心好了,loading万岁~

其实单纯的压缩质量遇到稍大的图片,会导致页面高频计算,然后页面基本就用不了了- -。有尝试过用iphone的一个屏幕截图(10M左右),压的时候稍过一会,整个手机都在发烫,只能杀进程。

所以,若对长度没有特殊的限制,可以做一个缩放,去加快压缩的进度,提高能压缩的图片大小上限。

页面到了ios上还是不行- -,可以看到最后图片level为0.001,最长边为764。
问题还是循环次数还是过多,计算频率太高。从图中可看出,对于大图来说,初始设定的level和图片尺寸过于宽松,可以优化一下初始level和尺寸。

有的时候还会遇到一张图片无论如何也压不到500k,就是上一次和这次的压缩后大小没有变化,这种情况需要抛错,不让循环继续。

大图片的等待时间稍长,可以给用户先预览一个base64的图片增加等待耐心,方法名为 getImgBase64 ,这里都一并给出了

解决的隐患:上面这个方案会出现我需要一个500k的照片,压到了520k之后,再压了一次。有时候这最后的一次会特别夸张,直接将图片弄到了几十k。
参考了: https://github.com/WangYuLue/image-conversion
这个库里面有个方法 compressAccurately ,这个方法可以比较精准地压缩。偷偷翻了一下源码。

其实上一个方案的痛点就在于,如何在每一个压缩循环里处理尺寸和压缩比例。

总结

如有纰漏,欢迎指正