mirror of
				https://github.com/dawidolko/Website-Templates.git
				synced 2025-10-27 16:03:10 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
 | |
| // This work is free. You can redistribute it and/or modify it
 | |
| // under the terms of the WTFPL, Version 2
 | |
| // For more information see LICENSE.txt or http://www.wtfpl.net/
 | |
| //
 | |
| // For more information, the home page:
 | |
| // http://pieroxy.net/blog/pages/color-finder/index.html
 | |
| //
 | |
| // Detection of the most prominent color in an image
 | |
| // version 1.1.1
 | |
| 
 | |
| function ColorFinder(colorFactorCallback) {
 | |
|   this.callback = colorFactorCallback;
 | |
|   this.getMostProminentColor = function(imgEl) {
 | |
|     var rgb = null;
 | |
|     if (!this.callback) this.callback = function() { return 1; };
 | |
|     var data = this.getImageData(imgEl);
 | |
|     rgb = this.getMostProminentRGBImpl(data, 6, rgb, this.callback);
 | |
|     rgb = this.getMostProminentRGBImpl(data, 4, rgb, this.callback);
 | |
|     rgb = this.getMostProminentRGBImpl(data, 2, rgb, this.callback);
 | |
|     rgb = this.getMostProminentRGBImpl(data, 0, rgb, this.callback);
 | |
|     return rgb;
 | |
|   };
 | |
| 
 | |
|   this.getImageData = function(imgEl, degrade, rgbMatch, colorFactorCallback) {
 | |
|     
 | |
|     var rgb,
 | |
|         canvas = document.createElement('canvas'),
 | |
|         context = canvas.getContext && canvas.getContext('2d'),
 | |
|         data, width, height, key,
 | |
|         i = -4,
 | |
|         db={},
 | |
|         length,r,g,b,
 | |
|         count = 0;
 | |
|     
 | |
|     if (!context) {
 | |
|       return defaultRGB;
 | |
|     }
 | |
|     
 | |
|     height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
 | |
|     width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;
 | |
|     
 | |
|     context.drawImage(imgEl, 0, 0);
 | |
|     
 | |
|     try {
 | |
|       data = context.getImageData(0, 0, width, height);
 | |
|     } catch(e) {
 | |
|       /* security error, img on diff domain */
 | |
|       return null;
 | |
|     }
 | |
| 
 | |
|     length = data.data.length;
 | |
|     
 | |
|     var factor = Math.max(1,Math.round(length/5000));
 | |
|     var result = {};
 | |
|     
 | |
|     while ( (i += 4*factor) < length ) {
 | |
|       if (data.data[i+3]>32) {
 | |
|         key = (data.data[i]>>degrade) + "," + (data.data[i+1]>>degrade) + "," + (data.data[i+2]>>degrade);
 | |
|         if (!result.hasOwnProperty(key)) {
 | |
|           rgb = {r:data.data[i], g:data.data[i+1], b:data.data[i+2],count:1};
 | |
|           rgb.weight = this.callback(rgb.r, rgb.g, rgb.b);
 | |
|           if (rgb.weight<=0) rgb.weight = 1e-10;
 | |
|           result[key]=rgb;
 | |
|         } else {
 | |
|           rgb=result[key];
 | |
|           rgb.count++;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| 
 | |
|   };
 | |
|   
 | |
|   this.getMostProminentRGBImpl = function(pixels, degrade, rgbMatch, colorFactorCallback) {
 | |
|     
 | |
|     var rgb = {r:0,g:0,b:0,count:0,d:degrade},
 | |
|         db={},
 | |
|         pixel,pixelKey,pixelGroupKey,
 | |
|         length,r,g,b,
 | |
|         count = 0;
 | |
|     
 | |
|     
 | |
|     for (pixelKey in pixels) {
 | |
|       pixel = pixels[pixelKey];
 | |
|       totalWeight = pixel.weight * pixel.count;
 | |
|       ++count;
 | |
|       if (this.doesRgbMatch(rgbMatch, pixel.r, pixel.g, pixel.b)) {
 | |
|         pixelGroupKey = (pixel.r>>degrade) + "," + (pixel.g>>degrade) + "," + (pixel.b>>degrade);
 | |
|         if (db.hasOwnProperty(pixelGroupKey))
 | |
|           db[pixelGroupKey]+=totalWeight;
 | |
|         else
 | |
|           db[pixelGroupKey]=totalWeight;
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     for (i in db) {
 | |
|       data = i.split(",");
 | |
|       r = data[0];
 | |
|       g = data[1];
 | |
|       b = data[2];
 | |
|       count = db[i];
 | |
|       
 | |
|       if (count>rgb.count) {
 | |
|         rgb.count = count;
 | |
|         data = i.split(",");
 | |
|         rgb.r = r;
 | |
|         rgb.g = g;
 | |
|         rgb.b = b;
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     return rgb;
 | |
|     
 | |
|   };
 | |
| 
 | |
|   this.doesRgbMatch = function(rgb,r,g,b) {
 | |
|     if (rgb==null) return true;
 | |
|     r = r >> rgb.d;
 | |
|     g = g >> rgb.d;
 | |
|     b = b >> rgb.d;
 | |
|     return rgb.r == r && rgb.g == g && rgb.b == b;
 | |
|   }
 | |
| 
 | |
| }
 |