需要在在线python编辑器里面实现生成二维码!这个之前用的skulpt里面不能实现,需要自己写一个函数,让它可以直接引入。
python
from MyQR import myqr
myqr.run(words="https://www.tudoubiancheng.top",picture="背景.png",version=30,colorized=True)
这里参考了这个大佬的文章! juejin.cn/post/698778... 写的非常详细
js
var $builtinmodule = function ($gbl, $loc) {
var myqr = {__name__: new Sk.builtin.str("myqr")};
var run_f = function(a, b, c, d) {
var a = Sk.ffi.remapToJs(a);
var b = Sk.ffi.remapToJs(b);
var c = Sk.ffi.remapToJs(c);
var d = Sk.ffi.remapToJs(d);
return a + b + c + d;
};
run_f.co_varnames = ['a', 'b', 'c', 'd'];
run_f.$defaults = [Sk.builtin.none, Sk.builtin.none, "hello", 12];
run_f.co_numargs = 2; // 使用Sk.builtin.func能让python理解这是个函数
myqr.run = new Sk.builtin.func(run_f);
return myqr;
}
在skulpt里面要这样引入
js
var externalLibs = {
"./myqr.js": "./MyQR.js",
};
function builtinRead(file) {
// 匹配外部模块
if (externalLibs[file] !== undefined) {
// 使用skulpt提供的promiseToSuspension,等待异步任务执行完才能继续
return Sk.misceval.promiseToSuspension(
fetch(externalLibs[file]).then(
function (resp) { return resp.text(); }
));
}
if (Sk.builtinFiles === undefined || Sk.builtinFiles.files[file] === undefined) {
throw "File not found: '" + file + "'";
}
// 匹配不到外部模块再从内置模块找
return Sk.builtinFiles.files[file];
}
这样初步实现在编辑器里面写,不会报错,且能找到我自己写的函数,然后就是要写生成二维码的函数了,这里我用到了Awesome-qr.js
库,这个可以实现彩色图片二维码
js
//静态的图片这样就可以实现
var reader = new FileReader();
reader.readAsDataURL(imgFile);
reader.onload = function () {
background = this.result;
new AwesomeQR.AwesomeQR({
text: a,
size: 500,
version: c,
backgroundImage: background,
whiteMargin: true,
}).draw().then((dataURL) => {
const imgQR = document.getElementById('imgQR');
imgQR.src = dataURL;
});
};
但是我还需要实现动态的gif图,里面也提供了gifBackground?: ArrayBuffer;
js
//这里和上面稍微有点不同
var reader = new FileReader();
reader.readAsArrayBuffer(imgFile);//需要的是一个buffer数组
reader.onload = function () {
background = this.result;
// background = toGrayGif(document.getElementById("imgPreview"))
new AwesomeQR.AwesomeQR({
text: a,
size: 500,
version: c,
gifBackground: background,
whiteMargin: true,
}).draw().then((dataURL) => {
const imgQR = document.getElementById('imgQR');
imgQR.src = dataURL;
});
};
到这里,正常可以实现生成动图或静态图的效果,但是传的参数里面还有一个是否为彩色!这个Awesome-qr.js
库里面没有提供,这里我看了一整天,开始用的是
js
function toGrayImg(img) {
// 获取画布
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
// 绘制图片
ctx.drawImage(img, 0, 0);
// 获取像素
var imgData = ctx.getImageData(0, 0, img.width, img.height);
console.log(imgData)
// 转换每个像素色值
for (var i = 0; i < imgData.data.length; i += 4) {
var r = imgData.data[i];
var g = imgData.data[i + 1];
var b = imgData.data[i + 2];
var gray = (r + g + b) / 3;
imgData.data[i] = gray;
imgData.data[i + 1] = gray;
imgData.data[i + 2] = gray;
}
// 写回画布
ctx.putImageData(imgData, 0, 0);
// 设置为源图片
img.src = canvas.toDataURL();
return img.src
}
但是gif图不能这样做,它正常只能设置第一帧为黑白,我需要遍历全部帧,然后在存到数组里面,进行一些操作,我试了很久,也没有搞出来,本来要放弃了,下午忽然想到能不能直接用css控制颜色呢?然后发现可以!所以前面纯纯大冤种~ 写一个样式,直接给img弄上就行了!
css
.black-and-white {
filter: grayscale(100%);
}
完成!