如何使用javascript检测图像内图标的宽度?

时间:2017-07-16 03:35:35

标签: javascript image icons width

我想检测图标的宽度(右手指针) 在下图中。

enter image description here

我认为可能的解决方案可能涉及color removal illustrated in this approach,在这种情况下可用于删除浅蓝色背景颜色。但我不确定去除颜色后的下一步。

1 个答案:

答案 0 :(得分:1)

我想出了什么!

以下是我的表现:

  1. 使用<img>标记(通过普通的ole-html或js)将图像添加到文档中
  2. 创建一个2D画布元素,使其大小与img
  3. 相同
  4. 使用context.drawImage
  5. 将图像绘制到画布上
  6. 使用context.getImageData获取画布中像素的颜色
  7. 将此原始数字数组转换为十六进制字符串颜色
  8. 按行图
  9. 将颜色分组为行
  10. 抓取图像的第一种颜色colorToFilter
  11. 创建minXminYmaxXmaxY变量,以跟踪不属于colorToFilter
  12. 遍历pixelMatrix中的每个像素,检查当前rowcolumn是否小于或大于colorToFilter <的颜色/ LI>
  13. 取消maxX - minXmaxY - minY的差异以及您的尺寸!
  14. 仅供参考:我因为跨域问题而使用数据uri作为图片src

    如果您需要更多解释,请与我们联系。这个解决方案可能不是最有效的,但它可以工作!

    &#13;
    &#13;
    /**
     * converts a number from 0-255 to a hex number padded with a zero if necessary
     * @param {number} number 
     */
    function toHex(number) {
      const numberAsString = Number(number).toString(16);
      return numberAsString.length === 1 ? '0' + numberAsString : numberAsString;
    }
    
    /**
     * Grabs the pixel colors from an image and stores it in a matrix
     * @param {HTMLImageElement} img 
     */
    function convertImageToPixelData(img) {
      // credit for getting the color of pixel comes from here:
      // https://stackoverflow.com/questions/8751020/how-to-get-a-pixels-x-y-coordinate-color-from-an-image
      const canvas = document.createElement('canvas');
      const imgWidth = img.clientWidth;
      const imgHeight = img.clientHeight;
      canvas.width = imgWidth;
      canvas.height = imgHeight;
      const context = canvas.getContext('2d');
      context.drawImage(img, 0, 0, imgWidth, imgHeight);
    
      const rawPixelData = context.getImageData(0, 0, imgWidth, imgHeight).data;
    
      // convert to hex string
      const pixelColors = rawPixelData.reduce((groups, pixelColor, index) => {
        if (index % 4 === 3) { // skip the alpha channel
          return groups;
        }
        if (groups[groups.length - 1].length === 6) {
          groups.push('');
        }
        groups[groups.length - 1] += toHex(pixelColor);
        return groups;
      }, ['']);
    
      // convert to matrix
      /**
       * @type {string[][]}
       */
      const pixelMatrix = pixelColors.reduce((matrix, pixel) => {
        const currentRow = matrix[matrix.length - 1];
        if (currentRow.length < imgWidth) {
          currentRow.push(pixel);
        } else {
          matrix.push([pixel]);
        }
        return matrix;
      }, [[]]);
      return pixelMatrix;
    }
    
    /**
     * finds the dimensions of an icon inside a single colored image
     * @param {HTMLImageElement} img 
     */
    function findBox(img) {
      const pixelMatrix = convertImageToPixelData(img);
      const colorToFilter = pixelMatrix[0][0];
    
      const imgWidth = img.clientWidth;
      const imgHeight = img.clientHeight;
    
      let maxX = 0;
      let minX = imgWidth;
      let maxY = 0;
      let minY = imgHeight;
    
      // for each pixel calculate if the index of the pixel is greater than the current max or min
      for (let row = 0; row < imgHeight; row += 1) {
        for (let column = 0; column < imgWidth; column += 1) {
          const pixel = pixelMatrix[row][column];
          if (pixel !== colorToFilter) {
            if (column < minX) {
              minX = column;
            }
            if (column > maxX) {
              maxX = column;
            }
            if (row < minY) {
              minY = row;
            }
            if (row > maxY) {
              maxY = row;
            }
          }
        }
      }
    
      const width = maxX - minX + 1;
      const height = maxY - minY + 1;
    
      return { width, height };
    }
    
    const img = document.querySelector('#my-image');
    
    const box = findBox(img);
    console.log(box);
    &#13;
    <img id="my-image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABkCAIAAADrOV6nAAAFUklEQVR42u3caVPaXByG8X7/D+AuakXBBQVFgiRhJyAgCpElICSAJkFQcFdQLKCt6/NYW8LWe+Z6pTOO429O+J+TxG+6hIj6um/4E4AQgRCBEIT4K4AQgRCBEIQIhAiECIQgRCBEIEQgBCECIQIhAiEIEQgRCBEIQYhA2DvlyQglOqclSiV5LKE4CPuntVggtbUkUyMiMSSaJ4u+leskUdv3JTgQ9nLxfVfYnvcuyNRoU44Yke3q8o7xTqAfsk9VMwkQ9thSC5hEz4LsmJbJR7YhyTJ55NJUwut3/LPcc/weCHskjvPOSubGRXJUts+WGO1pSHcRJWpp6gO2F92kQNgLRd2ifay55kj1WfITs1cJ+mIgDsIuT5juHZ3cWHzEsOxcvhXor/gZK475HItxppvTSjTjUUnNCXOiFDLVs1/wqyd0JXpY8mytYlPRtcklapXo1g6Bnjv/ysXznls7dasan5qS3ezDvrBbF89AUNu6eI4UmNXq71w8+c0bVldmZgqPY6p5QmR8loH262HC+HbeOd5imDqJmP//4lkXTJd+TdE2JrV2Fw1yyarJMh579AAHbN3JtLsuk8PNrZ5Nc/m7F0/yLrpSdk1KxHjOG1mNZcyRpDkSdfo9ga1WXjLmWE+04pyGDD2VJ191QKoOP+rAsZx3PabPBax8nHVxhyD8bNvXXEljRz5D7SuTy9NHIG+5SxHVpOUyYihvr75rpbGPPPu8pTKjLrmbFe2TMjUubw6LT0u8saWZKYV3LCD8aHJxSrbW5GKZLrObD1/3UzbBUkuuXwS1ReuoaFYV2QwIX/uFjbKldU5mX7zm6Z7ze7PWo4ulLZsVhC+GF3vLb7jA/MnFsyvVUsw2CH+141U1159L1y9+rfwsCH/mlajGEpyqcH3k1/hoDLlB+FSMkBsjjGP5rp+WIH2b4TDO/CyibxAWfMY+8qsLARabiq4QVlndOWu+4R1V4VfWL/4Q2zUf8XDY2r9sz6g04T2nr7i+N+9yJFbLzgmJ1PBs/r9+Hz0nWJP8y/z7bCrdaC+UFEw4YPsoSilCfvM6vHhsG5cd2hcHddRt8LtE63dwRtq+giI9JLpW2rxviy6duNUlRnseJ999l7rwzIosCNt3U0lwDon2xWonRxLOUNgDYfsKN7b25PxVR6dKl5gCYRsPSIPzIjFzmv4Xz1YG5Yx0RycR48dsB084+ZgehG0/oCkGLR3xs1b5XR/u2rc7j0QOycyaAvuKjXPf/LFfX8vS19tzJe/6/sA9jdEjhKmco83HpPW08YyZkqmZ8vOjN1Q1ojmyzGR3QahAMc9424bStPHUqy6558rba++fe6vHtAUXvQbCtkf51Z0aSqmr4EYYhMoMpaPH4Y5MpPveXRAqNJQeBYhOEPIRAoQK5BfpIcmj78Cm4jSdwzijSBnXsGhduFXWz1lJp/XYVCg50cyeCcps5wW/mE7YB/GN+156mpvdkNs00bTu8aoKTu0FRz4IpnPfbIGalgKRtQQIlS2es/3VGc39/vpFaKn5ZgU9W3nzMo1gPnNNS7sgVPqFmKBGojRXf/XMPFFNbt5//F1DJZwGodLt5unRUphSaJyppA9BqHirYYNs1d7gNm9fv19oDy4UfMa6As9fMxhnOpYltHEUIdtK6DlMDeBVtLfftY/nHKmwzDM3gqOatf75Xaes8yLTWw/v/jv/LuFNh6bmg7mJeJrlM4ET3n/28ePY1lrr6zeCr5hhQ8mcPjGweH1HiEAIQgRCBEIEQhAiECIQIhCCEIEQgRCBEIQIhAiECIQgRCBEIEQgBCECIQIhAiEIUe/0A1MOqyYF+UAcAAAAAElFTkSuQmCC">
    &#13;
    &#13;
    &#13;