// 中位切分法
/*** 颜色盒子类** @param {Array} colorRange [[rMin, rMax],[gMin, gMax], [bMin, bMax]] 颜色范围* @param {any} total 像素总数, imageData / 4* @param {any} data 像素数据集合*/
function ColorBox(colorRange, total, data) {lorRange = al = total;this.data = data;this.volume = (colorRange[0][1] - colorRange[0][0]) * (colorRange[1][1] - colorRange[1][0]) * (colorRange[2][1] - colorRange[2][0]);this.rank = al * (this.volume);
}Color = function () {var total = al;var data = this.data;var redCount = 0,greenCount = 0,blueCount = 0;for (var i = 0; i < total; i++) {redCount += data[i * 4];greenCount += data[i * 4 + 1];blueCount += data[i * 4 + 2];}return [parseInt(redCount / total), parseInt(greenCount / total), parseInt(blueCount / total)];
}// 获取切割边
function getCutSide(colorRange) {var arr = [];for (var i = 0; i < 3; i++) {arr.push(colorRange[i][1] - colorRange[i][0]);}return arr.indexOf(Math.max(arr[0], arr[1], arr[2]));
}// 切割颜色范围
function cutRange(colorRange, colorSide, cutValue) {var arr1 = [];var arr2 = [];colorRange.forEach(function (item) {arr1.push(item.slice());arr2.push(item.slice());})arr1[colorSide][1] = cutValue;arr2[colorSide][0] = cutValue;return [arr1, arr2];
}// 找到出现次数为中位数的颜色
function getMedianColor(colorCountMap, total) {var arr = [];for (var key in colorCountMap) {arr.push({color: parseInt(key),count: colorCountMap[key]})}var sortArr = __quickSort(arr);var medianCount = 0;var medianColor = 0;var medianIndex = Math.floor(sortArr.length / 2)for (var i = 0; i <= medianIndex; i++) {medianCount += sortArr[i].count;}return {color: parseInt(sortArr[medianIndex].color),count: medianCount}function __quickSort(arr) {if (arr.length <= 1) {return arr;}var pivotIndex = Math.floor(arr.length / 2),pivot = arr.splice(pivotIndex, 1)[0];var left = [],right = [];for (var i = 0; i < arr.length; i++) {if (arr[i].count <= unt) {left.push(arr[i]);}else {right.push(arr[i]);}}return __quickSort(left).concat([pivot], __quickSort(right));}
}// 切割颜色盒子
function cutBox(colorBox) {var colorRange = lorRange,cutSide = getCutSide(colorRange),colorCountMap = {},total = al,data = colorBox.data;// 统计出各个值的数量for (var i = 0; i < total; i++) {var color = data[i * 4 + cutSide];if (colorCountMap[color]) {colorCountMap[color] += 1;}else {colorCountMap[color] = 1;}}var medianColor = getMedianColor(colorCountMap, total);var cutValue = lor;var cutCount = unt;var newRange = cutRange(colorRange, cutSide, cutValue);var box1 = new ColorBox(newRange[0], cutCount, data.slice(0, cutCount * 4)),box2 = new ColorBox(newRange[1], total - cutCount, data.slice(cutCount * 4))return [box1, box2];
}// 队列切割
function queueCut(queue, num) {while (queue.length < num) {queue.sort(function (a, b) {return a.rank - b.rank});var colorBox = queue.pop();var result = cutBox(colorBox);queue = at(result);}return queue.slice(0, num);
}function getImageData(src) {return new Promise((resolve, reject) => {const canvas = ateElement('canvas');const context = Context('2d');const img = new Image();load = () => {canvas.height = img.height;canvas.width = img.width;context.drawImage(img, 0, 0)const data = ImageData(0, 0, img.width, img.height).dataresolve({ img, data })}r = () => reject(Error('Image loading failed.'))ssOrigin = ''img.src = src})
}// 亮度
function luminance(r, g, b) {var a = [r, g, b].map((v) => {v /= 255;return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);});return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}function getColors(color) {const lum1 = luminance(...color);let result = [];for (let r = 0; r <= 255; r += 5) {for (let g = 0; g <= 255; g += 5) {for (let b = 0; b <= 255; b += 5) {const lum2 = luminance(r, g, b);const brightest = Math.max(lum1, lum2);const darkest = Math.min(lum1, lum2);// 对比度if ((brightest + 0.05) / (darkest + 0.05) >= 16) {result.push([r, g, b]);}}}}const step = parseInt(result.length / 4);const array = [];for (let i = 0; i < 4; i++) {array.push(result[i * step]);}return array;
}export default function imageColor(url, callback) {var canvas = ateElement('canvas'),ctx = Context('2d'),width = 0,height = 0,imageData = null,length = 0,blockSize = 1,cubeArr = [];getImageData(url).then(({ img, data }) => {width = canvas.width = img.width;height = canvas.height = img.height;imageData = data;var total = imageData.length / 4;var rMin = 255,rMax = 0,gMin = 255,gMax = 0,bMin = 255,bMax = 0;// 获取范围for (var i = 0; i < total; i++) {var red = imageData[i * 4],green = imageData[i * 4 + 1],blue = imageData[i * 4 + 2];if (red < rMin) {rMin = red;}if (red > rMax) {rMax = red;}if (green < gMin) {gMin = green;}if (green > gMax) {gMax = green;}if (blue < bMin) {bMin = blue;}if (blue > bMax) {bMax = blue;}}var colorRange = [[rMin, rMax], [gMin, gMax], [bMin, bMax]];var colorBox = new ColorBox(colorRange, total, imageData);var colorBoxArr = queueCut([colorBox], 8);var colorArr = [];for (var j = 0; j < colorBoxArr.length; j++) {colorBoxArr[j].total && colorArr.push(colorBoxArr[j].getColor())}let r = 0, g = 0, b = 0;colorArr.forEach(c => {r += c[0];g += c[1];b += c[2];})const result = getColors([parseInt(r / colorArr.length), parseInt(g / colorArr.length), parseInt(b / colorArr.length)]);callback(result);})
}
本文发布于:2024-01-30 01:25:57,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170654915718254.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |