记录--前端如何截屏
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
前端常用的截图保存的方法
- 利用 Blob 对象和 URL.createObjectURL:可以将截图数据转换为 Blob 对象,然后使用
URL.createObjectURL
方法生成一个临时的 URL,将这个 URL 赋值给<a>
标签的href
属性,再设置download
属性为所需的文件名,这样用户点击链接时会自动下载图片文件。 - 利用 canvas 的 toDataURL 方法:可以将截图绘制到一个 canvas 元素上,然后使用 canvas 的
toDataURL
方法将 canvas 中的内容转换为 data URL,再创建一个临时的<a>
标签,将 data URL 赋值给href
属性,设置download
属性为所需的文件名,从而实现下载功能。
利用 Blob 对象和 URL.createObjectURL
- **生成 Blob 对象:**首先,将截图数据转换为 Blob 对象。Blob 对象是用于表示二进制数据的对象,可以通过将数据传递给 Blob 构造函数来创建。在这个场景中,截图数据通常是 base64 编码的字符串,需要将其解码为二进制数据,然后再转换为 Blob 对象。
- **创建临时 URL:**使用
URL.createObjectURL
方法生成一个临时的 URL。这个 URL 指向 Blob 对象的内容。生成的 URL 是唯一的,且在页面关闭时会被自动释放,因此称为临时 URL。 - **创建下载链接:**将生成的临时 URL 赋值给
<a>
标签的href
属性。同时,设置download
属性为所需的文件名,这样用户点击链接时会自动下载图片文件。
利用 canvas 的 toDataURL 方法
- **绘制到 canvas:**将截图数据绘制到一个 canvas 元素上。首先,创建一个新的 canvas 元素,并设置其大小与所需的截图大小相同。然后,使用 JavaScript 将截图数据绘制到这个 canvas 上。
- **转换为 data URL:**使用 canvas 的
toDataURL
方法将 canvas 中的内容转换为 data URL。这个方法可以将 canvas 中的图像数据转换为 base64 编码的字符串,表示为一个 URL。 - **创建下载链接:**将生成的 data URL 赋值给
<a>
标签的href
属性,同时设置download
属性为所需的文件名。用户点击链接时会自动下载图片文件。
微信小程序
如果是微信小程序中,因为不是 html,处理会有差别。在微信小程序中,要实现截图功能,可以使用小程序官方提供的 wx.canvasToTempFilePath
接口。这个接口可以将 Canvas 中的内容转换为临时文件路径,从而实现截图功能。
具体步骤如下:
- 创建一个
<canvas>
元素,并将需要截图的内容绘制到这个 Canvas 上。 - 调用
wx.canvasToTempFilePath
接口将 Canvas 中的内容转换为临时文件路径。 - 获取到临时文件路径后,可以进行后续的操作,例如保存到相册、上传到服务器等。
Node.js
上面看到现在由于有各种端,不一定支持 html 或者 canvas,并且各个设备、端上不能保证完全一致,所以可以在后端直接生成图片,前端根据链接下载截图。
在 Node.js 中实现截图和截长图的功能可以使用 Puppeteer 库。Puppeteer 是一个由 Google 开发的 Node.js 库,它提供了一个高级 API 来通过 Chromium 或者 Chrome 控制浏览器的行为。利用 Puppeteer,可以模拟浏览器的行为,并实现在浏览器中进行截图和截长图的功能。
在使用 Puppeteer 实现截图和截长图的过程中,需要注意以下几点:
- **安装 Puppeteer:**首先需要安装 Puppeteer 库,可以通过 npm 进行安装:
npm install puppeteer
。 - **使用 Puppeteer 截图:**使用 Puppeteer 提供的 API,可以直接在浏览器中打开网页,并将网页内容截图保存为图片。
- **实现截长图:**要实现截取长图的功能,可以模拟页面的滚动,并多次截取不同部分的内容,然后将截取到的内容拼接成一张长图。
- **兼容浏览器和微信小程序:**Puppeteer 库是针对 Node.js 环境开发的,不能直接在浏览器或者微信小程序中使用。如果要在浏览器或者微信小程序中实现截图和截长图的功能,可以考虑使用前面提到的浏览器中截图的方法或者小程序中截图的方法。
Puppeteer
在 Puppeteer 中实现截取长图的功能相对复杂,因为 Puppeteer 默认只能截取当前视口(Viewport)的内容,无法直接截取整个页面的内容。但可以通过模拟页面的滚动,并多次截取不同部分的内容,然后将截取到的内容拼接成一张长图来实现。
以下是一种实现截取长图的方法:
-
**设置视口大小:**首先,需要设置页面的视口大小,以确保可以显示所有要截取的内容。可以使用
page.setViewport()
方法设置页面的宽度和高度。 -
**模拟页面滚动:**通过执行 JavaScript 代码来模拟页面的滚动,以便逐步截取页面的不同部分。可以使用
page.evaluate()
方法来执行 JavaScript 代码。 -
**多次截取内容:**在模拟滚动的过程中,每次滚动一定的距离后,使用
page.screenshot()
方法截取当前视口的内容,并保存为图片。 -
**拼接截图:**将截取到的多张图片拼接成一张长图。可以使用第三方库来实现图片拼接的功能,比如
merge-img
。
下面是一个简单的示例代码,演示如何在 Puppeteer 中实现截取长图的功能:
const puppeteer = require('puppeteer'); const mergeImg = require('merge-img'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport({ width: 1200, height: 800 }); // 设置页面视口大小 await page.goto('https://example.com'); // 打开页面 const chunks = []; // 存储截取的图片数据 const scrollHeight = await page.evaluate(() => { // 模拟页面滚动,返回页面的滚动高度 const distance = 800; // 每次滚动的距离 let totalHeight = 0; const timer = setInterval(() => { window.scrollBy(0, distance); totalHeight += distance; if (totalHeight >= document.body.scrollHeight) { clearInterval(timer); } }, 100); return document.body.scrollHeight; }); for (let i = 0; i < scrollHeight; i += 800) { // 每次滚动800px,截取当前视口的内容并保存为图片 const screenshot = await page.screenshot({ clip: { x: 0, y: i, width: 1200, height: 800 } }); chunks.push(screenshot); } await browser.close(); // 拼接截取的图片 const mergedImg = await mergeImg(chunks, { direction: true }); // 保存拼接后的长图 await mergedImg.write('long_screenshot.png'); })();