pnjpng图像转换jpgABCCECom

转载请注明出处:
本篇文章翻译自谷歌出的优化视频里面的光头佬(Colt McAnlis),,以下正文:
便携式网络图型( Portable Network Graphics [PNG])在过去几十年已经变成App开发里重要的组成部分。它广泛的运用在游戏开发、网页开发和Android开发里,但也可能被大量的滥用。
正如我之前,PNG是一个不错和高分辨率的图片格式,但也意味着对于数据压缩率来说我们有很多的提高空间。在探讨怎么压缩PNG文件前,我们首先得知道PNG格式的原理。
PNG的压缩过程是完全无损的,压缩过的文件可以准确的还原出原图,这要分两个阶段完成:推断(又称过滤[filtering])和压缩。
差分编码()是最强大的数字压缩法之一。原理是根据前一个数据的值将后面的值替换成其他值,例如:
[2,3,4,5,6,7,8]可以变成[2,1,1,1,1,1,1],算法是
[2, 3-2=1, 4-3=1, 5-4=1, 6-5=1, 7-6=1, 8-7=1]
这样看就很明显了,如果你的数据是线性相关的(线性相关的意思是,一组数据里的前后值都差别不大,或者具有相关性),就可以把你的数据集转换成一组重复的、低的值,这样的值更容易被压缩。
PNG格式使用了差分编码(Delta encoding)里的过滤。原理是,对于每一行的像素,一个当前的像素都跟它的左边像素、上边的像素和左上角的像素有关系。
举个例子,如果我们要编码一个给定的像素通过它与A和B平均值的差异(X-(A+B)/2),那么我们将得到:
我们使用了ABC去推断出X的值,然后我们将X替换成更小的值。
需要注意的是,每一行的像素都有可能不同,PNG允许5种不同的推断算法,它们是:
X-(A+B)/2(又称平均值)
Paeth推断(A,B,C的线性方法,这种比较复杂可看)
这里说明一下,每一行像素应该选择最适合的过滤算法,这样才能得到最少数量的特殊值。下面是我们关于不同模式的例子:
需要注意的是这些过滤器都是对每一行像素起作用而不是单个像素。也就是说过滤器会对每一行的红色像素起作用,再分别对蓝色的像素起作用。(尽管同一行的像素会用同样的过滤器)
现在PNG格式在选择过滤器上有一些不错的方法,开发人员根据对不同类型图片的使用经验摸索出一些不错的规律。例如对于调色板的图像(palette images)和8位的灰色图就不要过滤。对于其他图片,就选择那种能最大限度地减少绝对差异总和的值的过滤器:将所有值的绝对值相加,然后对比不同过滤器得到的值,选择那个相加起来得到最小值的过滤器。
在一行像素被过滤后,就会执行DEFLATE压缩,这是LZ77延伸出来的一种算法。该算法结合了LZ77编码和哈夫曼编码,它跟PKWARE、PKZIP、GZIP等差不多相同。这种实现方式虽然是现成的,但用在压缩图片数据上,还是有一些需要注意的点:
Deflate算法只能匹配3到258个之间符号,所以最大的压缩比只能到1035:1;
如果匹配到的符号小于3,那么你会产生一些额外的开销来表示这些符号;
上面的这两点意味着你的图片大小会受到每一行像素的匹配程度影响。
你可以看一下面这两张图片,左边那张270x90的图只有20k,而右边那张270x92的图是左边那张的2倍大。
这似乎不符合逻辑,一张图片多540像素在压缩率上就少了一半。不过我们看仔细点,就能知道原因了,下面这张图表示压缩器怎么去压缩一个给定的像素的。深蓝色代表压缩率很高的区域,黄色/红色代表没怎么被压缩的区域。
这是怎么出现的呢,原因是小图的每一行像素的匹配度更高,那么它的压缩率就更高。你要是调整了大小,匹配度一变化,这种情况就有可能出现。一些潜在的匹配对象不在压缩区域里,它们没有匹配到,这就又可能导致出现一张大图。
如果你想知道你的PNG图片的压缩率如何,可以下个看一下。
对于格式的理解
值得注意的是,PNG格式不仅仅只有在过滤和压缩两个层面,PNG还是一种非常易扩展的容器格式,它可以支持各种类型的图片和附加数据。
首先PNG文件格式里面包含不同的区块(chunks),各个区块带有不同类型的数据。例如,PNG的Header chunks(头部块)就包含有图片的宽度、高度、位的深度和颜色类型;
图片的数据块(Image data chunk)包含了实际的图像信息(数据块可以有多个)。除此之外有一个单独的区块来记录颜色调色板(palette chunk)。最后就是图片的结束区块了(end-of-file chunk)。上面的这些都是主要区块,但也有一大堆附加区块,例如:
默认的背景色
色度如何显示白点上的坐标
图像γ数据块
文本数据,语言或元数据信息
颜色空间信息
立体图像数据
图像最后修改时间数据块
图像透明数据块
上面的这些区块是你特别需要注意的地方,因为很多垃圾信息是在图片编辑软件编辑后添加进去的。举个例子,你在Photoshop保存了一张PNG格式图片,这行图片里就会有一个区块记录着”这张图片是由photshop创建的”。这样的信息对于一张显示给人看的图片并没什么鸟用,但它还是会包含在图片里。因此,删除没有的区块是减少文件大小的关键。下面是一张16X16像素的图片,左边那张是Photoshop保存的普通图片,右边那张是用了photoshop的”导出web格式”选项保存的图片,这个选项会去掉了所有的附加信息。
PNG也支持很多种类型的像素格式,你可以选择一种最佳的:
Indexed(索引色) = 1个频道,可以为1,2,4,8 bpc
Grayscale(灰度) = 1个频道,可以为1,2,4,8,16 bpc
Gray+Alpha(带透明通道的灰度) = 2个频道,可以为8或16 bpc
Truecolor(RGB 真彩色) = 3个频道,可以为8或16 bpc
RGBA(RGBA 带透明通道的真彩色) = 4个频道,可以为8或16 bpc
像素格式是图片作者自己选择,我没多大的兴趣讨论,只要你确保选择正确的像素格式,不要把一张灰度图片保存为RGB/RGBA就行了。
GIF和PNG诞生的故事
在今天,当你打开一个大量内容的网页时,图片是最大的承载者。(尽管有一种观点认为视频将稍后赶超)
但真正让人感兴趣的是,尽可能多的压缩可以解决一些网页的臃肿问题,每个人都应该着手去压缩图片。
先让我们回到1985年,当时Unisys公司申请了LZW压缩算法专利,没人对它感兴趣。几年后,CompuServe公司发明了89A格式(也就是后来的GIF格式),他们用了LZW算法作为主要实现方式,没有意识到LZW是受专利保护的。而Unisys公司并没在意,直到1993年,网景浏览器增加了对IMG HTML标签的支持,并将89a格式一并支持。那一年动图就风靡于互联网上,之后Unisys就开始执行专利保护。1994年12月CompuServe和Unisys在法院上达成协议,Unisys将对所有使用89a格式图片的软件收取专利许可费。在这个协议宣布后的几个月里,一群工程师开发了一种全新的免专利的格式,这就是大家所熟知的PNG格式。
2004年,LZW算法专利终于过期,但在这10年里,GIF/PNG图片格式之争一直是网络的热点话题。
PNG是一种非常灵活和强大的图片格式类型,支持透明度的能力也使它在网页流行起来。但它并不适用于任何一种情况,在工作上使用最适用你的工具才是硬道理。如果你的图片是摄影作品且你对无损没有要求的话,JPG
或其他一些有损的处理方法可能更有效。不过你要是需要一种更小的像素格式,或者需要支持透明通道,那么PNG就绝对要比JPG好。
如果你对PNG编码器的核心技术感兴趣的话,可以看看这个叼炸天的,仅仅40行代码就把它搞定。
当然,如果你用WebP格式,小容量和无损都不是问题。不过,那就是另外一篇文章了。
一些翻译时候找的参考资料:
由于文人水平有限,如有翻译得不好的地方,请留言讨论。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:22129次
排名:千里之外
原创:15篇
评论:32条
(1)(4)(1)(1)(1)(1)(1)(2)(2)(3)(1)(1)(1)(2)(1)怎么把PNG图像变成JPEG_百度知道
怎么把PNG图像变成JPEG
旦锭测瓜爻盖诧睡超精我参加CF喷图大赛但是上传不到,我看见别人的全是ACDSee JPEG的图片.我上传到我再加100分!
我有更好的答案
---精品小软--- 双击下载
ABC多能图像转换---Advanced Batch Converter 3.8.20.rar 1,399KB 极好的图旦锭测瓜爻盖诧睡超精片格式转换,极其保真解压,打开“ABC”打开图片,点保存,选格式“JPEG”有许多格式,效果都非常好!
你好,很高兴为你解答。***互相学习***利人利己***告诉你一个最简单的办法
直接使用这个软件,任何格式都可以转换,是中文的,一看就懂。下载地址
重新从PS里打开。然后选择文件菜单,另存为,在保存时,选择类型成JPG,就可了。然后保存。OK/
打开图片,复制到,在保存时把格式改一下,如图
其他类似问题
为您推荐:
您可能关注的推广
png的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁前言svg 是一种矢量图形,在 web 上应用很广泛,但是很多时候由于应用的场景,常常需要将 svg 转为 png 格式,下载到本地等。随着浏览器对 HTML 5 的支持度越来越高,我们可以把 svg 转为 png 的工作交给浏览器来完成。一般方式创建 imageimage,src = xxx.创建 canvas,dragImage 将图片贴到 canvas 上;利用 toDataUrl 函数,将 canvas 的表示为 url;new image, src = url, download = download.png;但是,在转换的时候有时有时会碰到如下的如下的两个问题:问题 1 :浏览器对 canvas 限制Canvas 的 W3C 的标准上没有提及 canvas 的最大高/宽度和面积,但是每个厂商的浏览器出于浏览器性能的考虑,在不同的平台上设置了最大的高/宽度或者是渲染面积,超过了这个阈值渲染的结果会是空白。测试了几种浏览器的 canvas 性能如下:chrome (版本 46.0.-bit))最大面积:268, 435, 456 px^2 = 16, 384 px * 16, 384 px最大宽/高:32, 767 pxfirefox (版本 42.0)最大面积:32, 767 px * 16, 384 px最大宽/高:32, 767pxsafari (版本 9.0.1 (.2))最大面积: 268, 435, 456 px^2 = 16, 384 px * 16, 384 pxie 10(版本 10.0.)最大宽/高: 8, 192px * 8, 192px在一般的 web 应用中,可能很少会超过这些限制。但是,如果超过了这些限制,则会导致导出为空白或者由于内存泄露造成浏览器崩溃。而且从另一方面来说,导出 png 也是一项很消耗内存的操作,粗略估算一下,导出 16, 384 px * 16, 384 px 的 svg 会消耗 16384 * 16384 * 4 / 1024 / 1024 = 1024 M 的内存。所以,在接近这些极限值的时候,浏览器也会反应变慢,能否导出成功也跟系统的可用内存大小等等都有关系。对于这个问题,有如下两种解决方法:将数据发送给后端,在后端完成转换;前端将 svg 切分成多个图片导出;第一种方法可以使用 PhantomJS、inkscape、ImageMagick 等工具,相对来说比较简单,这里我们主要探讨第二种解决方法。svg 切分成多个图片导出思路:浏览器虽然对 canvas 有尺寸和面积的限制,但是对于 image 元素并没有明确的限制,也就是第一步生成的 image 其实显示是正常的,我们要做的只是在第二步 dragImage 的时候分多次将 image 元素切分并贴到 canvas 上然后下载下来。 同时,应注意到 image 的载入是一个异步的过程。关键代码:// 构造 svg Url,此处省略将 svg 经字符过滤后转为 url 的过程。var svgUrl = DomURL.createObjectURL(blob);var svgWidth = document.querySelector('#kity_svg').getAttribute('width');var svgHeight = document.querySelector('#kity_svg').getAttribute('height');// 分片的宽度和高度,可根据浏览器做适配var w0 = 8192;var h0 = 8192;// 每行和每列能容纳的分片数var M = Math.ceil(svgWidth / w0);var N = Math.ceil(svgHeight / h0);var idx = 0;loadImage(svgUrl).then(function(img) {
while(idx & M * N) {
// 要分割的面片在 image 上的坐标和尺寸
var targetX = idx % M * w0,
targetY = idx / M * h0,
targetW = (idx + 1) % M ? w0 : (svgWidth - (M - 1) * w0),
targetH = idx &= (N - 1) * M ? (svgHeight - (N - 1) * h0) : h0;
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = targetW;
canvas.height = targetH;
ctx.drawImage(img, targetX, targetY, targetW, targetH, 0, 0, targetW, targetH);
console.log('now it is ' + idx);
// 准备在前端下载
var a = document.createElement('a');
a.download = 'naotu-' + idx + '.png';
a.href = canvas.toDataURL('image/png');
var clickEvent = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': false
a.dispatchEvent(clickEvent);
}}, function(err) {
console.log(err);});// 加载 imagefunction loadImage(url) {
return new Promise(function(resolve, reject) {
var image = new Image();
image.src = url;
image.crossOrigin = 'Anonymous';
image.onload = function() {
resolve(this);
image.onerror = function(err) {
reject(err);
});}说明:由于在前端下载有浏览器兼容性、用户体验等问题,在实际中,可能需要将生成后的数据发送到后端,并作为一个压缩包下载。分片的尺寸这里使用的是 8192 * 9192,在实际中,为了增强兼容性和体验,可以根据浏览器和平台做适配,例如在 iOS 下的 safari 的最大面积是 。问题 2 :导出包含图片的 svg在导出的时候,还会碰到另一个问题:如果 svg 里面包含图片,你会发现通过以上方法导出的 png 里面,原来的图片是不显示的。一般认为是 svg 里面包含的图片跨域了,但是如果你把这个图片换成本域的图片,还是会出现这种情况。图片中上部分是导出前的 svg,下图是导出后的 png。svg 中的图片是本域的,在导出后不显示。问题来源我们按照文章最开始提出的步骤,逐步排查,会发现在第一步的时候,svg 中的图片就不显示了。也就是,当 image 元素的 src 为一个 svg,并且 svg 里面包含图片,那么被包含的图片是不会显示的,即使这个图片是本域的。W3C 关于这个问题并没有做说明,最后在 https://bugzilla.mozilla.org/show_bug.cgi?id=628747 找到了关于这个问题的说明。意思是:禁止这么做是出于安全考虑,svg 里面引用的所有 外部资源 包括 image, stylesheet, script 等都会被阻止。里面还举了一个例子:假设没有这个限制,如果一个论坛允许用户上传这样的 svg 作为头像,就有可能出现这样的场景,一位黑客上传 svg 作为头像,里面包含代码:&image xlink:href=&/myimage.png&&(假设这位黑客拥有对于
的控制权),那么这位黑客就完全能做到下面的事情:只要有人查看他的资料, 就会接收到一次 ping 的请求(进而可以拿到查看者的 ip);可以做到对于不同的 ip 地址的人展示不一样的头像;可以随时更换头像的外观(而不用通过论坛管理员的审核)。看到这里,大概就明白了整个问题的来龙去脉了,当然还有一点原因可能是避免图像递归。解决办法思路:由于安全因素,其实第一步的时候,图片已经显示不出来了。那么我们现在考虑的方法是在第一步之后遍历 svg 的结构,将所有的 image 元素的 url、位置和尺寸保存下来。在第三步之后,按顺序贴到 canvas 上。这样,最后导出的 png 图片就会有 svg 里面的 image。关键代码:// 此处略去生成 svg url 的过程var svgUrl = DomURL.createObjectURL(blob);var svgWidth = document.querySelector('#kity_svg').getAttribute('width');var svgHeight = document.querySelector('#kity_svg').getAttribute('height');var embededImages = document.querySelectorAll('#kity_svg image');// 由 nodeList 转为 arrayembededImages = Array.prototype.slice.call(embededImages);// 加载底层的图loadImage(svgUrl).then(function(img) {var canvas = document.createElement('canvas'),ctx = canvas.getContext(&2d&);canvas.width = svgWidth;canvas.height = svgHeight;ctx.drawImage(img, 0, 0);
// 遍历 svg 里面所有的 image 元素
embededImages.reduce(function(sequence, svgImg){
return sequence.then(function() {
var url = svgImg.getAttribute('xlink:href') + 'abc',
dX = svgImg.getAttribute('x'),
dY = svgImg.getAttribute('y'),
dWidth = svgImg.getAttribute('width'),
dHeight = svgImg.getAttribute('height');
return loadImage(url).then(function(sImg) {
ctx.drawImage(sImg, 0, 0, sImg.width, sImg.height, dX, dY, dWidth, dHeight);
}, function(err) {
console.log(err);
}, function(err) {
console.log(err);
}, Promise.resolve()).then(function() {
// 准备在前端下载
var a = document.createElement(&a&);
a.download = 'download.png';
a.href = canvas.toDataURL(&image/png&);
var clickEvent = new MouseEvent(&click&, {
&view&: window,
&bubbles&: true,
&cancelable&: false
a.dispatchEvent(clickEvent);
}, function(err) {
console.log(err);
// 省略了 loadImage 函数
// 代码和第一个例子相同说明:例子中 svg 里面的图像是根节点下面的,因此用于表示位置的 x, y 直接取来即可使用,在实际中,这些位置可能需要跟其他属性做一些运算之后得出。如果是基于 svg 库构建的,那么可以直接使用库里面用于定位的函数,比直接从底层运算更加方便和准确。我们这里讨论的是本域的图片的导出问题,跨域的图片由于「污染了」画布,在执行 toDataUrl 函数的时候会报错。结语在这里和大家分享了在前端将 svg 转为 png 的方法和过程中可能会遇到的两个问题,一个是浏览器对 canvas 的尺寸限制,另一个是导出图片的问题。当然,这两个问题还有其他的解决方法,同时由于知识所限,本文内容难免有纰漏,欢迎大家批评指正。最后感谢 @techird和 @Naxior 关于这两个问题的讨论。文章来源:/blog/2015/11/convert-svg-to-png-at-frontend/产品微博:Alibaba国际质量保证部||QQ交流群:产品地址:iTest爱测试前端测试服务前端综合性测试服务第一平台请长按识别2维码订阅关注iTest微信公众号iTest爱测试(iTestqianduan) 
 文章为作者独立观点,不代表微头条立场
的最新文章
现在,如果有程序猿说不知道Docker,这将是难以想象的。百科是这样描述Docker的。“Docker是do随着持续集成的走热,与之相伴的持续部署测试环境也是非常重要的一个环节。如果以为持续部署测试环境只是通过Shell脚本进行代码的编译,配置及部署这么简单的话,你会发现事实上远没有那么简单。Node.js是一个面向服务器的框架,立足于Chrome强大的V8 JS引擎。尽管它由C++编写而成,但是它在日常需求的测试过程中,因为时间和资源的相对紧张,往往会遇到PRD不够细致,而UC描述也过于简单的情况,这个前言
最近,在网上看到过一个调查,调查的内容是“程序员在项目开发中编写单元测试的情本文是WOT2016互联网运维与开发者大会的现场干货,
新一届主题为WOT2016企业安全技术峰会将在20据IDC报告,预计到2020年全球数据总量将超过40ZB(相当于4万亿GB),这一数据量是2013年的10倍十年以前,软件在一年之内的交付次数屈指可数。过去的十年间,交付的过程一直被不断地优化和改进。从早期的RUP模作为互联网产品来说,我们可以认为产品一直都在beta阶段,为什么这么说。两个原因一个是是我们需要用户的真实现代化的软件实践往往是敏捷开发、持续集成以及自动化测试等概念的组合。Bing的开发团队最近改变了他们的开发模概述相对前端技术快速发展的今天,测试这块显得有点冷清,原因有很多:可能在于测试的价值体现、在于测试的持续跟踪互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous inte分布式系统的测试是一个比较大的话题,在这里,我们仅用几个阿里云飞天分布式系统测试中比较有特点的实践方式来阐述测试人员到底应该做些什么?我仅仅是和我的团队一起讨论这个问题,就有一大堆答案出现了:  · 应该测试  ·软件测试是一门需要不断学习补充新知识的学科,要想成为一名优秀的测试员就必须像成为一名武林高手一样不断研习武艺谨以此文献给每一个为成为优秀全栈工程师奋斗的人。  技术在过去的几十年里进步很快,也将在未来的几十年里发展得如果我是一个技术大牛,极具产品sense,还凑巧精通Origami、AI、PS,我完全可以一个人做款APP,评审的不仅是需求  需求是为业务发展服务的,如果需求缺陷被引入线上,导致了用户的需求未得到满足,服务质量降低最近,我和我的同事有一个有趣的讨论。我们回顾了各自的工作历史,以及我们“丰富多彩”的个性是否对我们长远发展阿里巴巴集团2016财年GMV突破3万亿元人民币,有望在财年内超越沃尔玛,跃升成为全世界最大零售平台。“ 在任何一个时代,一款优秀的产品背后必定有一只优秀的团队做支撑。有目共睹,链家在过去的一年里成绩斐然。我不我见识了很多公司常常会犯这样或那样的错误,下面我具体谈谈在这些错误中最不可饶恕的7个:1.概述  软件开发周期估算是IT人员经常提到的一个概念,那么究竟什么是软件开发周期估算呢?为了适应当今世界经济社会和政治的动态、快速响应、高效发展的需要,作为实施开放计算、开放标准的开放源代码软件这在日常需求的测试过程中,因为时间和资源的相对紧张,往往会遇到PRD不够细致,而UC描述也过于简单的情况,acqueline Vermette是一名QA经理,拥有25年质量保证,质量监控,功能分析和编程经验。在这个总结感慨日,我还是不能免俗,写点东西吧,写给自己,这段旅程值得记录一下。记录也是新的开始。一年半了,我当下最热的Web前端框架概览作为前端工程师,我们生在最好的时代。标题中提到的三大前端框架都即将或已经发布了重日,第10界主题为“融合”的D2大会在阿里巴巴西溪园区4号楼报告厅如期举行,itest作接口是一系列可调用方法的集合。何为接口编程?接口编程是指当写一个函数或一个方法时,我们应该更加关注具体的接口四个月前,我从一所代码学校毕业,这所烂学校只教了我Ruby和Ruby on Rails的基本知识。一个星期后什么是垂直对齐?举个小例子:int robert_age = 32;int annalouise_age =小学生作文的开头:光阴似箭,日月如梭.....半年过去了,床底下又多了不少书,更新一个2.0版。自从技术书的凯文·凯利演讲;来源:2015产业中国年会我生活在硅谷,一个未来能快速转化为现实的地方,但是我很高兴能来到中前言svg 是一种矢量图形,在 web 上应用很广泛,但是很多时候由于应用的场景,常常需要将 svg 转为 事实上,程序员也是如此,大多时候他们只是坐在桌上的电脑前敲敲打打,这一过程在旁人看来是漫长而无趣的。为了避免本文作者:郑钦洪_(简书)1.前言对于对象的归档,之前使用MJ老师的MJExtension框架做字典转模型的设计测试案例的时候,需要有清晰的测试思路,对要测试什么,按照什么顺序测试,覆盖哪些需求做到心中有数。测试用例创业是一件比上班艰难数万倍的事情,它是小众的,低概率的,如果你找到了一个方向和一片市场,由于内心的需要而不是10月28日,Sort Benchmark官方宣布,阿里云用377秒完成了100TB的数据排序,打破了此前A分享一些有关程序员在努力修复bug时常说的话和冒出的想法。当氛围变得紧张的时候,这些话就会显得轻松幽默。最终产品测试法产品测试一般都是围绕需求为主的产品需求设计说明书PRD文档来展开测试的,针对每个功能点编写测试用例如果我告诉你有一个人一辈子没穿过皮鞋,你的第一反应会是什么?没钱?还是因为他是一名动物保护主义者?但事实上真效率高的明显好处是——单位时间内,能完成更多工作。但这只是冰山一角,假如工作速度快,你就会倾向于低估做事的成对缺陷的度量有助于测试过程监控,例如:缺陷密度分析,发现和修复的缺陷数目等。另外,缺陷度量应包括追踪过程控制1.流程的意义从一个软件企业的长远发展来看,如果要提高产品的质量首先应当从流程抓起,规范软件产品的开发过程。iTestqianduaniTest是一款致力于解决前端测试痛的自动化综合测试平台,以简单高效为服务宗旨,提供了不写代码的UI自动化-AUI、多浏览器下的页面截图和JS检测-PMI、浏览器测试环境-MTE以及网页源码中的坏死链检测-PI。热门文章最新文章iTestqianduaniTest是一款致力于解决前端测试痛的自动化综合测试平台,以简单高效为服务宗旨,提供了不写代码的UI自动化-AUI、多浏览器下的页面截图和JS检测-PMI、浏览器测试环境-MTE以及网页源码中的坏死链检测-PI。

我要回帖

更多关于 png图像 的文章

 

随机推荐