<p>Interesting approach using RGB to get the average colour.</p>
<p>In the past I've answered a vaguely similar question but <a href="https://stackoverflow.com/questions/15583514/image-retrieval-system-by-colour-from-the-web-using-c-with-openframeworks/15721464#15721464">doing basic image search based on average colour</a>. Instead of RGB colour space I've used <a href="https://en.wikipedia.org/wiki/CIELAB_color_space" rel="nofollow noreferrer">L<em>a</em>b* colour space</a> which is a perceptual colour space. I simply used this implementation of the <code>rgb2xyz -&gt; xyz2lab</code> and back formulas from <a href="http://web.archive.org/web/20111126054554/http://cookbooks.adobe.com/post_Useful_color_equations__RGB_to_LAB_converter-14227.html" rel="nofollow noreferrer">here</a> (if you take out a few keywords and types that syntax is pretty much javascript btw)</p>
<p>You might get slightly better results, but based on the demo you posted hopefully not extremely dissimilar. Does it justify the complexity: not sure.</p>
<p>Speaking of complexity you could go all the way to deep neural networks. Doing a quick search, <a href="https://arxiv.org/abs/1710.00756v2" rel="nofollow noreferrer">Progressive Color Transfer with Dense Semantic Correspondences</a> along with a <a href="https://github.com/rassilon712/Neural_Color_Transfer" rel="nofollow noreferrer">related implementation</a>. Maybe in a roundabout way that PyTorch model could be trained and exported to Tensorflow.js (<code>PyTorch -&gt; ONNX -&gt; TensorFlow -&gt; TensorFlow.js</code>) and used directly or integrated with <a href="https://learn.ml5js.org/#/reference/style-transfer" rel="nofollow noreferrer">ml5.js similar to the StyleTransfer model</a>.
Maybe it could produce interesting results, but it will surely be a complex approach.</p>
<p>If you already know the average RGB colour of an image and you're after an approximation/similar look how about &quot;faking it&quot; by simply tinting the image via <a href="https://p5js.org/reference/#/p5/tint" rel="nofollow noreferrer"><code>tint()</code></a>. You could even control the amount of tint using the 4th(alpha) argument:</p>
<pre><code>// apply 50% of refRgb
tint(refRgb[0], refRgb[1], refRgb[2], 128);
image(theImageYouWanTinted, 0, 0);
</code></pre>
<p>Sure the output will be a mixture of the source image and refRgb, but it's super easy to test if visually it achieves what you're after.</p>
<p>You could then expand and try other things, for example:</p>
<ul>
<li>use the grayscale version of the image you want to tint instead of the rgb one</li>
<li>based on the image content's perhaps a single colour channel would have more dominant / appealing features (e.g. instead of true grayscale use either red, green or blue channel as grayscale)</li>
<li>further filter the source image to try and extract relevant information (e.g. smooth the image a bit with a median filter, try a low pass filter, etc.)</li>
</ul>
<p>It's hard to gauge how precise and complex things need to be: I'd simply go for <code>tint()</code> first. (If you need to &quot;freeze&quot; the tinted result to pixels remember you could always get a &quot;snapshot&quot; of what's been drawn using <code>get()</code> and more complex things could be achieved using a p5.Graphics layer (see <a href="https://p5js.org/reference/#/p5/createGraphics" rel="nofollow noreferrer"><code>createGraphics()</code></a>));</p>
How do I add a color filter to an image so that its average RGB gets closer to that color?
<p>I have a 100x100 image:</p>
<pre><code>&lt;img id=&quot;my-face&quot; src=&quot;/my-face.jpg&quot; /&gt;
</code></pre>
<p>I get all of its pixels and I <a href="https://stackoverflow.com/a/2541680/2272048">calculate the average RGB</a> of that image:</p>
<pre><code>let img = document.getElementById('my-face')
let avgRgbOfImg = getAverageRGb(img)
</code></pre>
<p>I also have a reference RGB of a different color:</p>
<pre><code>let refRgb = [255, 244, 50] // yellow
</code></pre>
<p>I know now want to add a filter to the image, so that the <code>avgRgbOfImg</code> gets pretty close to my <code>refRgb</code>:</p>
<pre><code>addFilter(refRgb).to(img)
let newAvgRgb = getAverageRGb(img) // should be pretty close to `refRgb` (yellow)
</code></pre>
<p>In simpler terms, I have an image and I want to use canvas (or p5.js) to add a color filter to it so that it's <code>avgRgbOfImg</code> gets pretty close to that color.</p>
<p>Is there some canvas/p5 sets of methods to achieve this ?</p>