广告
返回顶部
首页 > 资讯 > 精选 >web浏览器端怎么实现
  • 283
分享到

web浏览器端怎么实现

2023-06-04 09:06:21 283人浏览 独家记忆
摘要

这篇文章主要介绍“WEB浏览器端怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“web浏览器端怎么实现”文章能帮助大家解决问题。浏览器端实现方案开发:大事件长图和专辑详情页大事件tab的视觉效

这篇文章主要介绍“WEB浏览器端怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“web浏览器端怎么实现”文章能帮助大家解决问题。

浏览器端实现方案

开发:大事件长图和专辑详情页大事件tab的视觉效果基本一致,如果能复用可以减少开发时间。

开发:怎么复用呢?

于是便有了下面在浏览器端尝试dom转图片的两种方案:

html2canvas

html2canvas一个在浏览器端通过js对整个或部分页面进行“截屏”的库。

html2canvas使用方法简单,截屏的核心代码如下:

let imgBase64;html2canvas(htm,{   onrendered : function(canvas){    //生成base64图片数据    imgBase64 = canvas.toDataURL();});

使用简单,但是坑不少,遇到的坑及解决方案:

1.截图模糊

主要解决思路:

1)将canvas的width和height属性放大为2倍。

2)将canvas的CSS样式width和height设置为原先1倍的大小。

<canvas width="200" height="100" style="width:100px;height:50px;"></canvas>
2.截图不全

源码获取dom高度不准确,修改源码,获取高度后手动传,修改方式如下:

源码:

return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {        if (typeof(options.onrendered) === "function") {            log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");            options.onrendered(canvas);        }        return canvas;});

修改后

//添加自定义高度宽度    var width = options.width != null ? options.width : node.ownerDocument.defaultView.innerWidth;    var height = options.height != null ? options.height : node.ownerDocument.defaultView.innerHeight;    return renderDocument(node.ownerDocument, options, width, height, index).then(function (canvas) {        if (typeof(options.onrendered) === "function") {            log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");            options.onrendered(canvas);        }        return canvas;    });
3.截图慢

截图慢得从html2canvas的原理说起,html2canvas并不是真正的截图,而是遍历加载的页面DOM,收集所有元素的信息,然后基于从DOM读取的属性使用canvas来绘制。

基于这个截图原理,慢的问题优化空间不大,而且html2canvas还有些CSS的限制,它只能正确地呈现它支持的CSS属性,完整的CSS属性支持列表,可以在官网查看。

关于慢,最简单的解决方案是在用户操作前提前生成截图。

4.crash

html2canvas截图后,将图片的base64传到客户端的分享组件,当base64超过500k可能导致客户端卡死或crash,如果慢的问题还能忍,那这个问题是真的没法接受的。

svg

除了html2canvas网上也有更轻量更快的库,这些库是基于svg的,尝试了下确实比html2canvas快很多。

svg方案的尝试:

//要转成图片的domlet htm = '<svg xmlns="Http://www.w3.org/2000/svg" width="100%" height="auto"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml"><div>这里是页面内容...</div></div></foreignObject></svg>';let DOMURL = window.URL || window.webkitURL || window;let canvas = document.createElement('canvas');let ctx = canvas.getContext('2d');let img = new Image();let svg = new Blob([htm], {type: 'image/svg+xml;charset=utf-8'});let url = DOMURL.createObjectURL(svg);let imgBase64;img.onload = function () {  ctx.drawImage(img, 0, 0);  imgBase64 = canvas.toDataURL();}img.src = url;

svg方案没法绕过的坑:

1.iOS下不支持跨域图片

由于安全限制,ios下跨域图片加crossOrigin属性也没法绕过跨域问题。

2.crash

和html2canvas一样,svg转图片后最终也是转base64传分享组件,base64超过500K可能导致的卡死和crash问题也存在。

服务器端实现方案

开发:浏览器端的方案crash问题不能忍,不如在服务器端生成图片,传图片URL到分享组件?

本着最大限度复用代码的初衷,首选了无头浏览器phantomjs截图的方案。

PhantomJS

PhantomJS是基于WebKit内核的无头浏览器,提供浏览器环境的命令行接口,我们可以进行网页截图、抓取网页数据等操作,更多详情可以去PhantomJS官网查看。

安装PhantomJS时,注意安装以下依赖:

sudo yum -y install GCc gcc-c++ make flex bison gperf ruby openssl-devel freetype-devel fontconfig-devel libicu-devel sqlite-devel libpng-devel libjpeg-devel

服务器端方案选择的是phantomjs-node库,实现截图的核心代码如下

var sitepage = null; var phInstance = null; phantom.create()     .then(instance => {         phInstance = instance;         return instance.createPage();     })     .then(page => {         let htm = [             '<!DOCTYPE html>',             '<html>',             '<head>',                 '<meta charset="utf-8">',             '</head>',             '<body style="background:#fff">',                 '<div>'+ new Date() +'</div>',             '</body>',             '</html>'         ].join("");         page.property('content',htm);         page.render('./test.png').then((err) => {             phInstance.exit()         }).catch(err => {             phInstance.exit();         })     })     .catch(error => {         phInstance.exit();     });

PhantomJS遇到的坑也不少,主要是环境问题:

1.没截图生成

开发:在Mac上和windows上生成截图正常,部署到测试环境后不能生成截图,打印PhantomJS日志,没有明确的报错信息。linux下权限问题?

查看PhantomJS和目录权限,PhantomJS没有写权限,修复权限问题,图片仍然不能生成。

开发:字母命名的截图正常生成,不支持图片文件名包含数字?

一番验证,截图名包含数字phantomjs-node不能正常生成图片文件。

2.截图空白

开发:颜色和图案均能够渲染到截图中,只有文字不能渲染,字体有问题?

确认测试机中字体目录为空,更新字体,文字终于能正常渲染到截图中。

3.截图模糊

又是模糊问题…

css使用相对rem单位,PhantomJS截图是设置缩放参数:

//csshtml{font-size: 100px;}.owner_avatar{width:.30rem;height: .30rem;border-radius: .30rem;margin-right: .10rem;}.events_img{width: .50rem;height:.50rem;}//phantomjs缩放处理page.property('viewportSize',{width:828,height:736});page.property('zoomFactor',2)page.property('content',htm);
4.截图加载慢

模糊问题设置2倍图后,图片大小暴涨到6M+,导致加载慢,设置截图质量:

page.render(fileName,{quality:85}).then((err) => {    phInstance.exit();})
5.截图慢

PhantomJS生成一个最简单的截图,耗时2S左右,这个速度显然是不能接受的,暂时没找到比较好的优化方式。

node canvas

node canvas扩展了canvas api以提供与节点的接口,例如流式传输PNG数据,转换为Buffer实例等,更多介绍可以去node canvas官网查看。

node canvas的环境搭建比较麻烦,依赖库与PhantomJS类似,这里就不列举了。

绘制图片的核心代码:

const { createCanvas, loadImage } = require('canvas');const canvas = createCanvas(200, 200);const ctx = canvas.getContext('2d');ctx.font = '30px';ctx.fillText('test', 50, 100);loadImage('test.jpg').then((image) => {  ctx.drawImage(image, 0, 0, 70, 70);})

node canvas与下面imagemagick的方案对比,imagemagick的性能更好,node canvas没再深入只实现了简单demo,踩坑不多。

ImageMagick 与 GraphicsMagick

ImageMagick是一套功能强大、稳定而且免费的工具集和开发包,可以用来读、写和处理超过90种的图片文件,包括流行的TIFF、JPEG、GIF、 PNG、pdf以及PhotoCD等格式。

ImageMagick可以根据web应用程序的需要动态生成图片, 还可以对一个(或一组)图片进行改变大小、旋转、锐化、减色或增加特效等操作,并将操作的结果以相同格式或其它格式保存,对图片的操作,即可以通过命令行进行,也可以用C/C++、Perl、Java、PHPpython或Ruby编程来完成。更多详情可在ImageMagick官网查看。

GraphicsMagick是从 ImageMagick 5.5.2 分支出来的,据说它变得更稳定和优秀,更多详情可在GraphicsMagick官网查看。

看起来GraphicsMagick是更好的选择,但是由于node gm这个库没有实现GraphicsMagick的半透明和圆角支持,而且针对专辑的大事件长图做了一些性能对比两者差异不大,所以选择使用ImageMagick。

node gm切换ImageMagick的方式非常简单,只要加以下设置:

var gm = require('gm');var imageMagick = gm.subClass({ imageMagick: true });

不可避免的,使用ImageMagick也遇到一些坑:

1.半透明遮罩

设计:专辑封面背景使用白透明遮罩,遮罩的颜色根据封面图来定,深色封面图用白色文字,浅色封面图用黑色文字。

开发:OK,先canvas获取封面图颜色信息,再判断颜色深浅

//RGB与YUV互转,Y>=128 为浅色Y'= 0.299*R' + 0.587*G' + 0.114*B'U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')V'= 0.615*R' - 0.515*G' - 0.100*B' = 0.877*(R'- Y')R' = Y' + 1.140*V'G' = Y' - 0.394*U' - 0.581*V'B' = Y' + 2.032*U'//ImageMagick设置透明色.fill("rgba(0,0,0,.5)")
2.头像圆角

设计:这些头像要用圆角哦。

开发:OK(还好ImageMagick支持圆角)

.fill("avatar.jpg").drawCircle(80,120,30,120)

ImageMagick圆角图片实现方式与canvas类似,画一个圆,然后用头像图片去填充来实现头像圆角。

3.昵称emoji表情

ImageMagick绘制昵称中的表情图比较麻烦,使用支持emoji的字体,尝试过Twitter的彩色emoji字体,但是ImageMagick有BUG,不能还原为彩色的。

最终解决方案:

1)使用等宽字体,方便计算精确的emoji位置

2)ImageMagick绘制昵称中的表情图片

.draw("image Over " + size + " " + url)

ImageMagick性能优化:

web浏览器端怎么实现

ImageMagick生成单张图片耗时100ms左右,但是并发请求多了平均耗时就暴涨到3S+,这个速度显然是不能接受的,经过一番优化后将平均耗时降到1S左右,主要优化点如下:

1.gm代码拼接,VM中执行

多次调用gm多次操作图片,严重影响性能,将图片操作代码拼接成字符串,在VM中执行,只调用一次gm,核心代码如下:

let sandbox = {    gm : imageMagick,    start : Date.now()}//计算图片高度let offset = getOffset();let qrcodeStr = getQrcodeStr();let titleStr = (function(){    return [        '.fontSize(24)',        '.fill("gray")',        '.drawText(164,152,"我是标题")'    ];})();let str = 'gm(828,'+ offset.height +',"#fff").font("'+ FONTS +'",48)'+ titleStr + qrcodeStr +'.quality(90).write("test.jpg",function(err){console.log(err || Date.now() - start)})';let script = new vm.Script(str);let context = vm.createContext(sandbox);script.runInContext(context);
2.mpc格式

mpc是ImageMagick提供的一种持久高速缓存格式,减少对图像格式进行解码和编码像素的开销。

mpc生成两个文件:

1)一个扩展名.mpc保留了与图像或图像序列相关的所有属性(例如宽度,高度,色彩空间等)。

2)一个扩展名.cache,是本地原始格式的像素缓存。

读取mpc图像文件时,ImageMagick读取图像属性,并将内存映射到磁盘上的像素缓存,无需解码图像像素,不过mpc的文件大小比其他图像格式大。

mpc图像文件适用于一次写入,多次读取模式,使用mpc将图像直接映射到内存,而不是每次重新读取和解压源图像。

3.Q8版本

ImageMagick Q16版本允许在不缩放的情况下读写16位图像,但像素缓存消耗的资源是Q8版本的两倍,Q8版本的执行速度通常比Q16版本要快。

像素缓存消耗 = 宽度*高度*位深度/ 8 *通道Q8位深 = 8 Q16位深 = 16通道 = 红 + 绿 + 蓝 + 阿尔法强度

关于“web浏览器端怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: web浏览器端怎么实现

本文链接: https://www.lsjlt.com/news/237160.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • web浏览器端怎么实现
    这篇文章主要介绍“web浏览器端怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“web浏览器端怎么实现”文章能帮助大家解决问题。浏览器端实现方案开发:大事件长图和专辑详情页大事件tab的视觉效...
    99+
    2023-06-04
  • web前端浏览器对象模型章节
    浏览器对象模型( browser object model )  什么是BOM    提起BOM就不得不提起JavaScript的构成。ECMAScript为JavaScript的核心,但是要是在浏览器中使用JavaScript,那么BOM...
    99+
    2023-06-05
  • Vue实现浏览器端扫码功能
    背景 不久前我做了关于获取浏览器摄像头并扫码识别的功能,本文中梳理了涉及到知识点及具体代码实现,整理成此篇文章内容。 本文主要介绍,通过使用基于 vue 技术栈的前端开发技术,在浏...
    99+
    2022-11-12
  • 浏览器怎么实现移动端高性能css3动画
    本篇内容主要讲解“浏览器怎么实现移动端高性能css3动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“浏览器怎么实现移动端高性能css3动画”吧!高性能移动We...
    99+
    2022-10-19
  • Ajax怎么实现客户端与浏览器异步交互
    今天小编给大家分享一下Ajax怎么实现客户端与浏览器异步交互的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一...
    99+
    2022-10-19
  • 怎么推送Web浏览器的通知
    这篇文章给大家介绍怎么推送Web浏览器的通知,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。你如何增加网站的流量?电子商务企业的主要目标是继续吸引现有用户并吸引新访客。通过发送电子邮件通知,短信提醒,社交媒体和网络推送通...
    99+
    2023-06-05
  • Qt怎么实现图片浏览器
    这篇文章主要介绍了Qt怎么实现图片浏览器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Qt怎么实现图片浏览器文章都会有所收获,下面我们一起来看看吧。图片浏览器逻辑实现图片浏览器用到了前面几乎所有的知识,包括窗口...
    99+
    2023-07-05
  • 怎么使用命令行浏览器在Linux终端上网浏览
    这篇文章给大家分享的是有关怎么使用命令行浏览器在Linux终端上网浏览的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Linux 用户的最佳终端 Web 浏览器注:此榜单排名不分先后。1、W3Mw3m 是...
    99+
    2023-06-15
  • 怎么判断PC端浏览器内核
    小编给大家分享一下怎么判断PC端浏览器内核,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!如何判断PC端浏览器内核XML/HTML...
    99+
    2022-10-19
  • Web Audio浏览器采集麦克风音频数据怎么实现
    今天小编给大家分享一下Web Audio浏览器采集麦克风音频数据怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
    99+
    2023-07-05
  • CSS怎么实现QQ浏览器功能
    这篇文章将为大家详细讲解有关CSS怎么实现QQ浏览器功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。知识点结合fullpage.js实现全屏滚动CSS中linear-gradient() 函数用于创建一...
    99+
    2023-06-08
  • 怎么判断当前浏览器是否是微信浏览器或者移动端
    怎么判断当前浏览器是否是微信浏览器或者移动端,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1,用JS代码判断浏览器是否为微信浏览器function is_weixn(...
    99+
    2023-06-20
  • jspXCMS浏览次数和浏览次数缓存怎么实现
    本文小编为大家详细介绍“jspXCMS浏览次数和浏览次数缓存怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“jspXCMS浏览次数和浏览次数缓存怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。文章的...
    99+
    2023-06-26
  • php怎么实现浏览记录
    本文操作环境:Windows7系统、PHP7.1版、DELL G3电脑php怎么实现浏览记录?php实现历史浏览记录其实原理很简单,就是利用cookie,实现记录,其中需要注意的点就是,设置一下,你需要保存的cookie长度,记录时间,下面...
    99+
    2017-05-26
    php
  • Javascript怎么实现浏览器本地存储
    今天小编给大家分享一下Javascript怎么实现浏览器本地存储的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我...
    99+
    2022-10-19
  • Java实现浏览器端大文件分片上传
    目录背景介绍 项目介绍 需要知识点 启动项目 项目示范 核心讲解核心原理 功能分析分块上传 秒传功能 断点续传 总结 参考文献 背景介绍   Breakpo...
    99+
    2022-11-12
  • 前端浏览器字体小于12px怎么办
    这篇文章将为大家详细讲解有关前端浏览器字体小于12px怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言最近做项目时,UI设计的字体10px,看效果图时发现字体仍然蛮大,改变12px时字体还是那么大...
    99+
    2023-06-08
  • Node怎么实现浏览器预览项目所有图片
    本文小编为大家详细介绍“Node怎么实现浏览器预览项目所有图片”,内容详细,步骤清晰,细节处理妥当,希望这篇“Node怎么实现浏览器预览项目所有图片”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在前端实际项目开发...
    99+
    2023-07-04
  • Web开发的网页浏览器现状是怎样的
    Web开发的网页浏览器现状是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。现在的互联网网络浏览器市场给我们呈现的是一个变...
    99+
    2022-10-19
  • 怎么提高Web页面浏览速度
    这篇文章主要讲解了“怎么提高Web页面浏览速度”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么提高Web页面浏览速度”吧!(1)减少html页面的大小。网...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作