Dynalay演示
一种在图像上创建动态文字叠加层的简单方法。点击此处查看。
截屏
先决条件
在本地运行此程序之前,您必须已安装以下软件。
- 节点
- Webpack
安装
它是用 Node.js 构建的,所以启动过程非常简单。
npm installnpm run start:dev
就这样,你会在 localhost:8080 上看到它运行。
贡献
欢迎大家为这个项目贡献力量,并像对待自己的项目一样对待它。😊
如果你开发过网页应用,肯定对这种情况很熟悉。很多时候,你需要给图片添加文字。如果图片是用户上传的,那么很难预测什么颜色的文字与图片搭配。请看以下示例:
“Rachel Rose”这个文字在深色背景上看起来很棒,但如果背景是白色呢?这可能会造成问题,因为你永远无法预测用户会上传什么内容。
一个简单的解决方法是像这样对图像使用模糊滤镜……
.image-blur{
filter: blur(1px);
}
或者在图像上添加一层深色图层。有很多方法可以做到这一点,但这些方法都依赖于对图像的修改。但是,如果我们不改变图像,而是改变文本颜色呢?
“为什么不呢?”这是我最近想到这个问题时对自己说的。那么,让我们在这篇文章中探讨一下如何做到这一点。
我创建了一个简单的页面来演示这个问题。如果你想边学边做,只需克隆这个仓库即可。
克隆完成后,使用此提交来检出未解决的问题。
git checkout 0817434
npm install
npm run start:dev
目前,我们的网页有两种背景:深色和浅色。网页上还有两个按钮用于切换背景。这是它最初的样子。
为了实现这一点,我们将使用画布。思路是将图像加载到画布中,然后获取图像的每一个像素。每个像素的颜色将被转换为其RGB值。因此,如果将这三个值取平均值,即可得到该像素的亮度(更多信息请点击此处)。这些值介于 0(最暗)和 255(最亮)之间。通过比较每个像素的亮度,我们可以判断图像是暗还是亮。
首先,创建一个函数,将背景中的 src 加载到隐藏img元素中。
const isDark = (src)=>{
//create a hidden img element
let img = document.createElement("img");
img.src = src;
img.style.display = "none";
document.body.appendChild(img);
}
然后使用以下方法在画布上绘制图像
const isDark = (src)=>{
//create a hidden img element
let img = document.createElement("img");
img.src = src;
img.style.display = "none";
document.body.appendChild(img);
img.onload = function() {
// create canvas
let canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(this,0,0);
}
}
现在我们需要获取每个像素的 RGB 值。为此,我们使用getImageData
let imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
输出结果将类似于
太好了!现在我们有了数据,但是它是一个巨大的数组,其中每个像素的 RGB 值都是像这样单独存储的。
所以我们需要像这样一起循环遍历它们四个。
let imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
let data = imageData.data;
let r,g,b,avg;
for(let x = 0, len = data.length; x < len; x+=4) {
r = data[x];
g = data[x+1];
b = data[x+2];
avg = Math.floor((r+g+b)/3);
}
avg现在得到了每个像素的平均RGB值。接下来,将所有像素的平均值相加,然后除以图像中的像素总数,即可得到平均亮度。
let brightness = Math.floor(colorSum / (this.width*this.height));
所以最终的函数看起来会像这样:
const isDark = (src) => {
return new Promise((resolve, reject) => {
//create a hidden img element
let img = document.createElement("img");
img.src = src;
img.style.display = "none";
document.body.appendChild(img);
let colorSum = 0;
img.onload = function () {
// create canvas
let canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
let data = imageData.data;
let r, g, b, avg;
for (let x = 0, len = data.length; x < len; x += 4) {
r = data[x];
g = data[x + 1];
b = data[x + 2];
avg = Math.floor((r + g + b) / 3);
colorSum += avg;
}
let brightness = Math.floor(colorSum / (this.width * this.height));
resolve(brightness >= 128 ? false : true);
}
});
}
我们用这个函数来检查图像是否偏暗。
isDark('./images/dbg.jpg').then((data) => {
dynamicHeader.classList.remove("light-text");
if(data) dynamicHeader.classList.add("light-text");
});
但好像少了点什么。啊哈,一点风格!
.dynamic-header {
transition: color 2s;
}
现在完美了。
希望你们喜欢这个小实验,并从中有所收获。实现相同结果的方法有很多,如果你有其他方法,欢迎在下方留言。你或许会想在实际项目中使用这个方法,或许不会,但我正在考虑将其开发成一个 npm 包,以便更进一步。如果你想参与,请私信我@sarthology或直接在下方留言。
好了各位!下次再见。感谢阅读。
文章来源:https://dev.to/xenoxdev/how-to-make-dynamic-text-overlays-on-images-dcc