uni-app 实现图片主题色的获取
<h1 id="uni-app-实现图片主题色的获取">uni-app 实现图片主题色的获取</h1><pre><code class="language-html"><canvas canvas-id="getImageThemeColorCanvas" id="getImageThemeColorCanvas">
</canvas>
</code></pre>
<p>canvas 元素默认宽为 300,高为 150。需要注意的是,上述代码不可或缺。</p>
<pre><code class="language-javascript">/**
* 获取图片主题色
* @param path
* 图片的路径,可以是相对路径,临时文件路径,存储文件路径,网络图片路径
* @param canvasId
* 画布表示
* @param callback
* 回调函数,返回图片主题色的 RGB 颜色值
*/
function getImageThemeColor(path, canvasId, callback) {
uni.getImageInfo({
src: path,
success: function (img) {
// 创建一个 Canvas 对象
const ctx = uni.createCanvasContext(canvasId);
// 将图片绘制到 Canvas 上
const imgWidth = 300;
const imgHeight = 150;
ctx.drawImage(img.path, 0, 0, imgWidth, imgHeight);
ctx.save();
ctx.draw(true, () => {
uni.canvasGetImageData({
canvasId: canvasId,
x: 0,
y: 0,
width: imgWidth,
height: imgHeight,
success(res) {
let data = res.data;
let arr = [];
let r = 1,
g = 1,
b = 1;
// 取所有像素的平均值
for (let row = 0; row < imgHeight; row++) {
for (let col = 0; col < imgWidth; col++) {
if (row == 0) {
r += data;
g += data;
b += data;
arr.push();
} else {
r += data[(imgWidth * row + col) * 4];
g += data[(imgWidth * row + col) * 4 + 1];
b += data[(imgWidth * row + col) * 4 + 2];
arr.push();
}
}
}
// 求取平均值
r /= imgWidth * imgHeight;
g /= imgWidth * imgHeight;
b /= imgWidth * imgHeight;
// 将最终的值取整
r = Math.round(r);
g = Math.round(g);
b = Math.round(b);
if (!!callback) {
// 返回图片主题色的 RGB 颜色值
callback(`${r},${g},${b}`);
}
},
});
});
},
});
}
</code></pre>
<p>上述代码通过使用 uni-app 的 API <code>uni.getImageInfo</code>、<code>uni.createCanvasContext</code>和<code>uni.canvasGetImageData</code> 实现图片主题色获取,以兼容 H5 和 微信小程序等,并以 canvas 默认的宽高进行绘制。</p>
<p>调用示例:</p>
<pre><code class="language-javascript">const imgUrl = "https://asset.example.com/bjpic/mscrmqh/temp/1691118468757.png";
getImageThemeColor(imgUrl, "getImageThemeColorCanvas", (retRGBColor) => {
console.log("retRGBColor", retRGBColor);
});
</code></pre>
<h2 id="解决-h5-在获取跨域网络图片主题色时报错">解决 H5 在获取跨域网络图片主题色时报错</h2>
<p>错误提示:</p>
<pre><code>canvasGetImageData:fail SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data."
</code></pre>
<p>跨域问题解决办法可参考:JavaScript 跨域问题</p>
<h3 id="以通过使用代理服务器解决为例">以通过使用代理服务器解决为例</h3>
<p>实现思路:跨域访问 -> 同源访问</p>
<p>通过代理,将<strong>跨域访问地址</strong>(<code>https://asset.example.com/bjpic/mscrmqh/temp/1691118468757.png</code>)替换为<strong>同源访问地址</strong>(<code>http://127.0.0.1:7788/bjpic/mscrmqh/temp/1691118397601.png</code>)</p>
<h4 id="开发环境配置">开发环境配置</h4>
<p>以下通过使用 Webpack 配置代理服务器为例:</p>
<pre><code class="language-js">// vue.config.js
module.exports = {
devServer: {
host: "0.0.0.0",
port: 9999,
proxy: {
"/bjpic": {
target: "https://asset.example.com",
},
},
},
};
</code></pre>
<h4 id="生产环境配置">生产环境配置</h4>
<p>以下通过使用 Nginx 配置代理服务器为例:</p>
<pre><code class="language-conf"># 代理跨域图片
location /bjpic {
proxy_pass https://asset.example.com;
}
</code></pre>
<p>在 H5 获取跨域网路图片主题色时,将图片地址替换为同源访问地址:<code>http://127.0.0.1:7788/bjpic/mscrmqh/temp/1691118397601.png</code></p>
<p>将上述调用示例修改为:</p>
<pre><code class="language-javascript">const imgUrl = "http://127.0.0.1:7788/bjpic/mscrmqh/temp/1691118397601.png";
getImageThemeColor(imgUrl, "getImageThemeColorCanvas", (retRGBColor) => {
console.log("retRGBColor", retRGBColor);
});
</code></pre><br><br>
来源:https://www.cnblogs.com/yuzhihui/p/17222889.html
頁:
[1]