因为使用js制作的截图功能不如意(将网页元素写入到canvas时 遇到 网页本身就有canvas标签时,网页本身的canvas变成空白图,同时图片有点模糊和失真),经过各种垂死挣扎后的尝试后,使用谷歌浏览器自带的截图功能,谷歌自带的截图功能可以通过谷歌插件调用。故需要制作一个可以和网页互动的插件。
谷歌插件文件:
manifest.js :插件配置文件
{
"name": "Screenshot Extension",
"version": "1.0",
"description": "A simple screenshot extension",
"background": {
"persistent": false,
"scripts": ["background.js"] // 设置隐藏标签页的js文件
},
"content_scripts": [
{
"matches" : ["http://www.map.com/*"], // 指定使用插件的域名
"js": ["content.js"]
}
],
"browser_action": {
"default_icon": "camera.png",
"default_title": "Screenshot"
},
"permissions": ["tabs", "<all_urls>", "activeTab"],
"web_accessible_resources": ["js/inject.js"],
"manifest_version": 2
}
content.js :与网页交互的js文件
// 通道初始化
var hiddenDiv = document.getElementById('myCustomEventDiv');
if(!hiddenDiv) {
hiddenDiv = document.createElement('div');
hiddenDiv.style.display = 'none';
hiddenDiv.setAttribute('id', 'myCustomEventDiv');
document.body.appendChild(hiddenDiv);
}
// 接收目标网页的请求
hiddenDiv.addEventListener('myCustomEvent', function() {
// console.log(hiddenDiv)
// var eventData = document.getElementById('myCustomEventDiv').innerText;
console.log('截图中...');
document.getElementById('myCustomEventDiv').innerText = '';
chrome.runtime.sendMessage({greeting: '你好,我是content-script呀,我主动发消息给后台!'}, function(response) {
// 收到浏览器后台的消息
console.log('截图完成');
setTimeout(function(){
window.postMessage({}, 'http://www.map.com');
},3000);
});
});
background.js :隐藏标签页,即插件页面执行的js
/*
* @Author: HappyCrab
* @Date: 2020-12-02 15:24:01
* @LastEditors: HappyCrab
* @LastEditTime: 2020-12-08 18:22:17
* @Description:
*/
var screenshot = {
content : document.createElement("canvas"),
data : '',
init : function() {
this.initEvents();
// setInterval(function(){
// // alert(document.getElementsByTagName('canvas').length)
// },8000)
},
saveScreenshot : function() {
var image = new Image();
image.onload = function() {
var canvas = screenshot.content;
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
// context.drawImage(img, 0, 0);
// 清除指定颜色为透明底
// var rgba = [ 178,34,34, 255]; // 需要清除的颜色
// var imgData = null;
// const [r0, g0, b0, a0] = rgba;
// var r, g, b, a;
// var tolerance = 100;
// imgData = context.getImageData(0, 0, image.width, image.height);
// console.log(imgData)
// for (let i = 0; i < imgData.data.length; i += 4) {
// r = imgData.data[i];
// g = imgData.data[i + 1];
// b = imgData.data[i + 2];
// a = imgData.data[i + 3];
// const t = Math.sqrt((r - r0) ** 2 + (g - g0) ** 2 + (b - b0) ** 2 + (a - a0) ** 2);
// if (t <= tolerance) {
// imgData.data[i] = 0;
// imgData.data[i + 1] = 0;
// imgData.data[i + 2] = 0;
// imgData.data[i + 3] = 0;
// }
// }
// context.putImageData(imgData, 0, 0);
// const newBase64 = canvas.toDataURL('image/png');
// img.src = newBase64;
// save the image
var link = document.createElement('a');
link.download = "download.png";
link.href = screenshot.content.toDataURL('image/png');
link.click();
screenshot.data = '';
};
image.src = screenshot.data;
},
initEvents : function() {
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.captureVisibleTab(null, {
format : "png",
quality : 100
}, function(data) {
screenshot.data = data;
// send an alert message to webpage
chrome.tabs.query({
active : true,
currentWindow : true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {ready : "ready"}, function(response) {
if (response.download === "download") {
screenshot.saveScreenshot();
}
else {
screenshot.data = '';
}
});
});
});
});
},
initEvents2 : function() {
chrome.tabs.captureVisibleTab(null, {
format : "png",
quality : 100
}, function(data) {
screenshot.data = data;
// send an alert message to webpage
chrome.tabs.query({
active : true,
currentWindow : true
}, function(tabs) {
screenshot.saveScreenshot();
});
});
},
/**清除图片背景颜色 **/
removeImgBg: function(img) {
//背景颜色 白色
const rgba = [255, 255, 255, 255];
// 容差大小
const tolerance = 60;
var imgData = null;
const [r0, g0, b0, a0] = rgba;
var r, g, b, a;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const w = img.width;
const h = img.height;
canvas.width = w;
canvas.height = h;
context.drawImage(img, 0, 0);
imgData = context.getImageData(0, 0, w, h);
for (let i = 0; i < imgData.data.length; i += 4) {
r = imgData.data[i];
g = imgData.data[i + 1];
b = imgData.data[i + 2];
a = imgData.data[i + 3];
const t = Math.sqrt((r - r0) ** 2 + (g - g0) ** 2 + (b - b0) ** 2 + (a - a0) ** 2);
if (t <= tolerance) {
imgData.data[i] = 0;
imgData.data[i + 1] = 0;
imgData.data[i + 2] = 0;
imgData.data[i + 3] = 0;
}
}
context.putImageData(imgData, 0, 0);
const newBase64 = canvas.toDataURL('image/png');
img.src = newBase64;
}
};
screenshot.init();
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
console.log("截图中")
screenshot.initEvents2()
// console.log('收到来自content-script的消息:');
// console.log(request, sender, sendResponse);
sendResponse('我是后台,我已收到你的消息:' + JSON.stringify(request));
});
插件调试需要打开插件的背景图页面显示 这个隐藏页,即 background.js 上打印的数据和报错数据都在 背景图上显示
网页给插件发送消息并接收请求结果
$("#keep_img").click(function() {
console.log('开始截图-1')
// 给插件发送消息
keep_img_num = 1;
fireCustomEvent('doing');
})
window.addEventListener("message", function(e){
console.log('收到截取完成响应')
})
// 插件消息初始化
var customEvent = document.createEvent('Event');
customEvent.initEvent('myCustomEvent', true, true);
function fireCustomEvent(data) {
hiddenDiv = document.getElementById('myCustomEventDiv');
hiddenDiv.innerText = data
hiddenDiv.dispatchEvent(customEvent);
}
插件下载:谷歌截图