Skip to main content
update wording
Source Link

I am trying to get the hex colours from an image. The problem I am having is that for some reason randomly the code causes high CPU usage, which times out the browser and I am not sure how to optimise the code. I am not sure where the high CPU usage is. I've tried adding set-timeoutdelays using setTimeout() but with no luck.

I am trying to get the hex colours from an image. The problem I am having for some reason randomly the code causes high CPU usage, which times out the browser and I am not sure how to optimise the code. I am not sure where the high CPU usage is. I've tried adding set-timeout but with no luck.

I am trying to get the hex colours from an image. The problem I am having is that for some reason randomly the code causes high CPU usage, which times out the browser and I am not sure how to optimise the code. I am not sure where the high CPU usage is. I've tried adding delays using setTimeout() but with no luck.

Tweeted twitter.com/StackCodeReview/status/1045599397269184514
deleted 46 characters in body; edited tags
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

Any help would be much appreciated. Thanks

Any help would be much appreciated. Thanks

Source Link
Limpep
  • 141
  • 2

Getting hex colours from a image

I am trying to get the hex colours from an image. The problem I am having for some reason randomly the code causes high CPU usage, which times out the browser and I am not sure how to optimise the code. I am not sure where the high CPU usage is. I've tried adding set-timeout but with no luck.

The code was original written in Javascript but I am converted it to Typescript,

Here is full code code which returns the hex values

import {Injectable} from '@angular/core';

@Injectable()
export class ExtractColours {

  private euclidean(p1, p2) {
    let s = 0;
    for (let i = 0, l = p1.length; i < l; i++) {
      s += Math.pow(p1[i] - p2[i], 2)
    }
    return Math.sqrt(s);
  }

  private calculateCenter(points, n) {
    let vals = [];
    let plen = 0;

    for (let i = 0; i < n; i++) { vals.push(0); }
    for (let i = 0, l = points.length; i < l; i++) {
      plen++;
      for (let j = 0; j < n; j++) {
        vals[j] += points[i][j];
      }
    }
    for (let i = 0; i < n; i++) {
      vals[i] = vals[i] / plen;
    }
    return vals;
  }

 
private kmeans(points, k, min_diff) {
    
        let plen = points.length;
        let clusters = [];
        let seen = [];
    
        while (clusters.length < k) {
          let idx = parseInt(String(Math.random() * plen));
          let found = false;
          for (let i = 0; i < seen.length; i++ ) {
            if (idx === seen[i]) {
              found = true;
              break;
            }
          }
          if (!found) {
            seen.push(idx);
            clusters.push([points[idx], [points[idx]]]);
          }
        }
   
        while (true) {
          let  plists = [];
          for (let i = 0; i < k; i++) {
            plists.push([]);
          }
    
          for (let j = 0; j < plen; j++) {
            let p = points[j];
            let smallest_distance = 10000000;
            let idx = 0;
    
            for (let i = 0; i < k; i++) {
              let distance = this.euclidean(p, clusters[i][0]);
              if (distance < smallest_distance) {
                smallest_distance = distance;
                idx = i;
              }
            }
            plists[idx].push(p);
          }
    
          let diff = 0;
    
          for (let i = 0; i < k; i++) {
            let old = clusters[i];
            let list = plists[i];
            let center = this.calculateCenter(plists[i], 3);
            let dist = this.euclidean(old[0], center);
            clusters[i] = [center, (plists[i])];
            diff = diff > dist ? diff : dist;
          }
          if (diff < min_diff) {
            break;
          }
        }
    
        return clusters;
      }
    

here I am converting the rgb to hex but I am also returning the alpha value

private rgbToHex(rgb) {
    
          function th(i) {
            let h = parseInt(i).toString(16);
            return h.length == 1 ? '0'+h : h;
          }
    
          let alpha = (parseInt(th(rgb[0]),16) + parseInt(th(rgb[1]),16) + parseInt(th(rgb[2]),16)) / 3;
    
        return parseInt(String(alpha)).toString(16) +'#' + th(rgb[0]) + th(rgb[1]) + th(rgb[2]) ;
      }
    
    
      public process_image(img, ctx) {
        let points = [];
    
        ctx.drawImage(img, 0, 0, 200, 200);
    
        let data = ctx.getImageData(0, 0, 200, 200).data;
    
        for (let i = 0, l = data.length; i < l;  i += 4) {
          let r = data[i];
          let g = data[i+1];
          let b = data[i+2];
          points.push([r, g, b]);
        }
        let results = this.kmeans(points, 3, 1);
        let hex = [];
        for (let i = 0; i < results.length; i++) {
          hex.push(this.rgbToHex(results[i][0]));
        }
    
        return hex;
      }
    }

Any help would be much appreciated. Thanks