Giter VIP home page Giter VIP logo

fast-average-color's Introduction

Fast Average Color

NPM version NPM Downloads bundlephobia install size Coveralls

Demo

A simple library that calculates average or dominant color of any images or videos in browser environment.

Features

  • Bet on speed
  • Some algorithms: simple, sqrt (default) and dominant
  • Small bundle size, tree shaking
  • Average color can be obtained from:
    • image
    • string (url of image or base64)
    • video
    • canvas or OffscreenCanvas
    • ImageBitmap
    • array of numbers, Uint8Array or Uint8ClampedArray
  • Average color can be obtained from specific part of resource
  • Support for transparency (PNG, SVG and other formats)
  • Support for web workers
  • Support for Node.js

Table of contents

Unhandled Rejection (SecurityError): The operation is insecure.

The crossOrigin attribute allows images that are loaded from external origins to be used in canvas like the one they were being loaded from the current origin. Using images without CORS approval taints the canvas. Once a canvas has been tainted, you can no longer pull data back out of the canvas. By loading the canvas from cross origin domain, you are tainting the canvas.

You can prevent this by setting crossorigin="anonymous".

See code

MIT License

Links

fast-average-color's People

Contributors

2xaa avatar adamjosefus avatar akkuma avatar arnemolland avatar dependabot[bot] avatar hcodes avatar rax7 avatar sevenoutman avatar thomasvaeth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fast-average-color's Issues

Comparison / Benchmarks

I think every library that claims to be fast needs a proper benchmark or comparison.

Other solutions, sorted by stars:

I kinda like your work the most just by looking at the examples. Thank you and keep it up!

Not working in IE

This is my code

const fac = new FastAverageColor();
const img = new Image();
img.crossOrigin = "anonymous";
img.src = event.poster;
fac.getColorAsync(img)
            .then((color) => {
                setColor(color);
            })
            .catch((e) => {
                console.log(e);
            })

Π‘Π½ΠΈΠΌΠΎΠΊ экрана 2020-06-30 Π² 2 48 48 PM

Can anyone help me with this error?

Typescript Importation Problem

Hey,

My problem is, that I'm simply unable to import the package after downloading it from npm, I'm using Typescript, via Angular. I'm not an expert but I'm having an issue that I never had before with a package.

I'm using the package as you said to :
import * as FastAverageColor from "fast-average-color"
const fac = new FastAverageColor();
"new FastAverageColor()": Cannot use 'new' with an expression whose type lacks a call or construct signature.

When I'm importing with the js way :
"const FastAverageColor = require('fast-average-color');"
I'm getting no error at first, but when I'm building, I get :
"Uncaught TypeError: FastAverageColor is not a constructor .."

So I don't know how to process, which step have I missed ?

Florian

Omit more than one colour

Is there a way to omit two (or more) colours, rather than just the one.. where maybe a two colour combination is providing an unfavourable average colour? (think dark blue and bright orange only, in a logo, with a white background - I still need to omit the white but the average colour of the blue and orange is a pale red which looks horrific and not complimentary at all!)

Weird Rollup Transformation

Thanks for this great package! I'm having this weird issue with rollup though where some of the source code is being transformed in a way such that it errors out on chrome.

Source Code

        let
            red = arr[i],
            green = arr[i + 1],
            blue = arr[i + 2],
            alpha = arr[i + 3];

From dominent.js

Transformed Source Code

`let,red=n[C],green=n[C+1],blue=n[C+2],alpha=n[C+3]`

Error
Uncaught SyntaxError: Unexpected strict mode reserved word which is caused by let, I think.

Solution
Place red = arr[i] on the same line as let. Also replace all other similar declarations using let in simple.js, sqrt.js and index.js.

One interesting thing to note is that similar style const declarations do work leading me to think this is some kind of bug with rollup?? Let me know what you think and thanks for the help!

Getting a palette of colors

I use this project in my product. Works great. However, to work with palettes, you have to use other projects, for example, https://github.com/lokesh/color-thief. It would be great if FAC in the dominant algorithm could return not only the dominant color, but a palette of colors sorted by volume.

getColorAsync - return a Promise

Can we make getColorAsync return a Promise?
It would break the .call on the callback, though.

Maybe a third getColor function is needed?
I suppose the user could also wrap this, but it would be nice to have out of the box if the callback wasn't supplied.

Willing to make a PR for this, just need direction on what the best approach is.

getColorFromArray4() returns gray color for a red image

Is this the correct usage?

const byteArray = new Uint8Array(hex.length / 2)
for (let i = 0; i < hex.length / 2; i++) {
  const index = i * 2
  byteArray[i] = Number.parseInt(hex.slice(index, index + 2), 16)
}

const rgba = fastAverageColor.prepareResult(fastAverageColor.getColorFromArray4(byteArray)).rgba

I'm trying to do the operation synchrously.

Example for a hex value is: 89504E470D0A1A0A0000000D4948445200000020000000200806000000737A7AF400000370494441545885AD576D72DA48107D3D925DF85774838C17E2925381684FB0F804E1064B4EB0EC09022758E704B16F404E607C8260D85A6B2BA2229F60E1572822E9ED0F240268C4977955FAC1B4E87ED33DDD6F24D803E58B6A030AEF04D010710078A9A90F724C2014A21BFC3BFCBCAB4FD9F682765D6DE1E403441A0238BB38253006D98DA7D69F61D81F1F4CA0E2D6DA14FCB16B60131121AE037FD0D98B80D69E639F2577F899E2E7A21F7D5757A66CE408E857AF3DCBB6EF0EDD7511088CE328BA0ABFFED32F24A0B5E75867C9B763075F21F15D9D2F67422D07B7CF92D59D930F246F093C1D10EC89E42DC8FB6C4D80ACB40B2C08D8A5A485B59A13B81EF9C3E6E871A049BE5F2142DE2F3F2426F3654C48BE1F3D0EF4C81F3699E07A8D9B57716BED255269ABC9E9975CEA995C05FEDFBDECA7D69E8393995EAFE3C2EEBA1AD3D27839C5FAD56BCFB6ED2F6B1B5B94C206000B27ED5DEA9E3A36060780D0F7C3DCA295984EBE6395E26B00CDB404D2303924446F23B50D5672626E65917700A0CA17D586085EE4821393786A759F4B209E593DD32116C0295F541B0A0AC6DD036C6D1BA3BB200CFB63906DA3D192BA12C098E663EC3EC3C81FDE98D685F4140C878FC4E418BB5F737A9F5B1379A120F2D6F0FA7F470D5E0C4F995645CC65790E28E68E524563566BEFA87A20C0CB1C29E04909991F1E00AC525CD01DFBA37C5135FA12325414314E36017E3F1601516899D629D25788D933192152FFE5B266FCE33E28BBD526447E331A63F6543CB37A9992AD43017F55DCDA87438357DC5A5B443E996C2426F1CCEA49CAF24644E629273A4CD8178576D6A2244211764174037F98EFE795A06FEA09D55B11B4367513818FA3C7416B21C7B69C7E4B0DE3388AAEF0E334B44B712F3727C887C01F1A05A67C59ED0AE622B30D1167E7A1EF870A486594E800A954DAF61D4A5327C28FC67A7998C03CD701C4515C685BDD043A9974AFDC092B6EB5FF33EDBC1DF9C3A6D69E93DE9640302C9AEB0B1F97356E0EBE9AC1FCA5B49484993C4751F46BD1EDE710027389577A5967CCD772CBEE652448DE086431AC367D646C22406212C7517DE3B57C41427B8EF10002081E079BBFA64C04C887686AD54D0A6B14A330EC8F037FE86507F359203A813FF48AE4DD482043E00FDA1167E7043ECEAFDBE681B5122F7D8FE46DC4D979E00F76EB8C6DD0DA73B4EB6E9569EDBA7A1F25FD1F1655BEBD33EDAD050000000049454E44AE426082

It is failure in the Mobile browser

Hi, it is no problem in the Google browser.But it has problem in the Mobile browser.
And it tips: ''error: DOMException" and i get the color is white.
Info: In React.
Code:
` imgRef = (e) => {
this.imgDom = e
};

handleImageLoaded = () => {
let that=this;
if(this.imgDom){
const fac = new FastAverageColor();
fac.getColorAsync(this.imgDom, function (color) {
that.setState({
bodyBgColor: color,
});
});
}
};

this.imgRef(e)} src={"https://n1-q.mafengwo.net/s13/M00/1D/C3/wKgEaVyhw-OARMlZAAHft8LZYM070.jpeg?imageMogr2%2Fthumbnail%2F%21750x750r%2Fstrip%2Fquality%2F90"} alt="" />
`

Library/package doesn't work?

Hello,

I am using this library for the first time, but I am having issues with it

I originally want to use it in reactjs, so I installed the npm package and followed the documentation.

However whatever image I chose, the hex color was always #000000. So I decided to try to use it on jsFiddle, so I used unpkg to load it, but the same issue occurs.

https://jsfiddle.net/wbmosfcu/3/

I tried to give the image url directly as parameter to the function but I also tried to put it on an image element and pass that as parameter argument.

I also tried to use the async function but that just gives me the same error

What am I doing wrong?

Omit colour from image?

This is a brilliant tool, thank you. Just a question really. I am using it on logos, a lot of which are on white backgrounds. The average colour coming back to me is always very pale as a result, or white when I set it to the dominant algorithm. Is there a way I can choose to omit a colour from the calculation? If not this would be a really handy addition. Thanks for all your hard work.

looking to calculate avg color for area within picture

I developed a browser extension that gives users the ability to choose a background dynamically (its just one part of what it does, it was designed to raise money for causes),
and using hsp algorithm to determine if the image is dark or light (based on google implementation i found in their background manager in chrome)

to determine the avg color of the image they check every 5 pixels

As you can see in the attached screenshot it works well, but there are cases where if the object
is centered and background is mostly bright, using avg for the whole picture seems not to do
the trick (see attached)
I'm looking for a way to make the same calculation but based on some grid
I wonder how to calculate a pixel location in data based on x,y or % or region
Do you have any suggestions? your help with this might get more users to support a good cause :)

---------------------------------
|      |                 |      |
|      |                 |      |
|      |                 |      |
|      |                 |      |
---------------------------------
---------------------------------

 

code used: (data is getImageData from canvas)
``` length = data.data.length;
        i=-4
        blockSize=5
        while ( (i += blockSize * 4) < length ) {
          ++count;
          rgb.r += data.data[i];
          rgb.g += data.data[i+1];
          rgb.b += data.data[i+2];
        }

        // ~~ used to floor values
        rgb.r = ~~(rgb.r/count);
        rgb.g = ~~(rgb.g/count);
        rgb.b = ~~(rgb.b/count);

Screenshot Dog black and white

Screenshot 2020-02-14 12 12 22
Screenshot 2020-02-14 12 12 48

Bugs in _simpleAlgorithm and _sqrtAlgorithm

In these functions, the color components are first divided by 255, and then multiplied by 255.

Second, in the sqrt version, the color components are first multiplied by alpha, and then squared. This is wrong, there must be an inverse order of operations.

Third, if the image is fully transparent, then by dividing by averageAlpha == 0, NaN is calculated.

I suggest:

function _simpleAlgorithm(arr, len, preparedStep) {
  let
    redTotal = 0,
    greenTotal = 0,
    blueTotal = 0,
    alphaTotal = 0,
    count = 0;

  for (let i = 0; i < len; i += preparedStep) {
    const
      red = arr[i],
      green = arr[i + 1],
      blue = arr[i + 2],
      alpha = arr[i + 3];

    redTotal += red * alpha;
    greenTotal += green * alpha;
    blueTotal += blue * alpha;
    alphaTotal += alpha;
    count++;
  }

  if (alphaTotal === 0) return [0, 0, 0, 0];

  return [
    Math.round(redTotal / alphaTotal),
    Math.round(greenTotal / alphaTotal),
    Math.round(blueTotal / alphaTotal),
    Math.round(alphaTotal / count)
  ];
}
function _sqrtAlgorithm(arr, len, preparedStep) {
  let
    redTotal = 0,
    greenTotal = 0,
    blueTotal = 0,
    alphaTotal = 0,
    count = 0;

  for (let i = 0; i < len; i += preparedStep) {
    const
      red = arr[i],
      green = arr[i + 1],
      blue = arr[i + 2],
      alpha = arr[i + 3];

    redTotal += red * red * alpha;
    greenTotal += green * green * alpha;
    blueTotal += blue * blue * alpha;
    alphaTotal += alpha;
    count++;
  }

  if (alphaTotal === 0) return [0, 0, 0, 0];

  return [
    Math.round(Math.sqrt(redTotal / alphaTotal)),
    Math.round(Math.sqrt(greenTotal / alphaTotal)),
    Math.round(Math.sqrt(blueTotal / alphaTotal)),
    Math.round(alphaTotal / count)
  ];
}

Firefox Resource Error

Hey there,

When using this lib, I'm getting the following error in Firefox: FastAverageColor: incorrect sizes for resource "https://y39t3.csb.app/IMT.svg".

Here is a sandbox where I'm getting the error. Be great if you can let me know what I'm doing wrong. I tried using an Image constructor but have the same error there too.

Can't find variable: Image

Calling

        const fac = new FastAverageColor();
        fac.getColorAsync(result.base64).then(color=>console.log(color));

Gives the error "[Unhandled promise rejection: ReferenceError: Can't find variable: Image]"

FastAverageColor.prototype.getColorAsync = function (resource, options) {
            var _a;
            if (!resource) {
                return Promise.reject(getError('call .getColorAsync() without resource.'));
            }
            if (typeof resource === 'string') {
                var img = new Image();
                img.crossOrigin = (_a = options === null || options === void 0 ? void 0 : options.crossOrigin) !== null && _a !== void 0 ? _a : '';
                img.src = resource;
                return this.bindImageEvents(img, options);
            }

the error is in the line var img = new Image();

When I ctrl + leftClick on Image in VSC it goes to a definition outside of the project, but native file from VSC: C:\Users\me\AppData\Local\Programs\Microsoft VS Code\resources\app\extensions\node_modules\typescript\lib\lib.dom.d.ts

Flakyness on Safari with a black color returned

Hey, thanks for the package πŸ‘

We are experiencing some flakyness on Safari only, sometimes (10% of the time +/-), the color returned is black even if the image seems to be loaded normally...

Any info or workaround for this ? Sorry if the answer is trivial but I couldn't find anything on the web after looking at this for hours..

πŸ‘‰ Once again, this is working 90% of the time on Safari and 100% of the time on other browsers (Chrome, Firefox, Brave)

Here is a snippet with the implementation and the values I'm getting, I have two images where I use fast-average-color, sometimes the two are returning a black color, here is a screenshot where one is working and the other one has returned a black color... (and sometimes both are returning black)

ℹ️ PS: Of course the two images are not black, they do not even have a small black part on it.

Capture d’écran 2023-07-06 aΜ€ 16 26 31

export const getDominantImageColor = (img: HTMLImageElement): string => {
  try {
    console.log('----------- 2 - GET DOMINANT COLOR --------------');
    console.log('----------- 2.1 img.complete --------------', img.complete);
    console.log('----------- 2.2 img.naturalHeight --------------', img.naturalHeight);
    console.log('----------- 2.3 img.naturalWidth --------------', img.naturalWidth);
    console.log(
      '----------- 2.3 loaded ??? --------------',
      img.complete && img.naturalHeight !== 0
    );
    const fac = new FastAverageColor();
    const dominantColor = fac.getColor(img);
    console.log('----------- 2.4 dominantColor --------------', dominantColor);
    return dominantColor.hex
  } catch (err: unknown) {
    console.log('err', err)
    return GRAY_500;
  }
};
// Safari version
Version 16.4

Please tell me if I need to provide more info..

Thanks πŸ™

Error import not found

I have several errors when installing the library in my project using typescript and Angular 15.

I use the last version 9.2.0

image

typescript error @ 6.4.1

Screenshot 2021-09-03 at 09 46 06

Not sure if this is a localised issue as I haven't had time to look into it, but I am getting this error on 6.4.1 (which I notice was updated 1 week ago) and I do not get the error on 6.4.0

fast_average_color_1.default is not a constructor

node @12.22.0
ts @4.5.2
fast-average-color @7.0.1

Usage:

import FastAverageColor from "fast-average-color"

const fac = new FastAverageColor()
const color = fac.getColorFromArray4(data, {ignoredColor: [255, 255, 255, 255]}).slice(0, 3)

I can see that it decompiles to:

const fac = new fast_average_color_1.default();

There was a similar issue raised (#48), but I'm following the usage specified there, and still getting the error.

Not getting dominant color from images with no background

Hi, thanks for the amazing work on the library. Unfortunately, I am having some issues extracting dominant colors from cutout(?) images i.e. images without any background. I'm getting white as the dominant color every time.

Screenshot 2021-09-10 at 12 04 53 AM

Stackblitz: https://stackblitz.com/edit/fac-dominant-issue?file=index.ts

I have some test images(1, 2) with which you can try it out.

I am using HTMLImageElement, is there anything to do with that? Because when the open the image in a new tab, I see a white background has been added. Any leads/help will be appreciated!

'resource.addEventListener is not a function' when using getColorAsync

I wanna get dominant color from images using getAsyncColor. When I do this code in my Vue component:

dominantColor: async function(categories) {
  let predominantColor = []

  for (let category of categories) {
    let fac = new FastAverageColor()
    fac.getColorAsync(this.URL + category.image, 
       { algorithm: 'dominant' })
       .then(color => {
            console.log(color)
       })
       .catch(function(e) {
            console.error(e)
       })
   }
}

Chrome logs with a resource.addEventListener is not a function error. What should I do for this?
category.image is being gotted from a Vuex array state and this.url is a base url.

Error

colored text

image
hello, I want to make like that, but it's not possible with the library

ReferenceError: Image is not defined

Using Node.js and trying to get the average color of a image url, but when it gets to it. I get this error.

C:\Users\assas\node_modules\fast-average-color\dist\index.common.js:163
return this._bindImageEvents(new Image(resource), options);
^

ReferenceError: Image is not defined
at FastAverageColor.getColorAsync (C:\Users\assas\node_modules\fast-average-color\dist\index.common.js:163:42)
at Request._callback (C:\Users\assas\Desktop\Metrix\main.js:192:13)
at Request.self.callback (C:\Users\assas\node_modules\request\request.js:185:22)
at Request.emit (events.js:311:20)
at Request. (C:\Users\assas\node_modules\request\request.js:1154:10)
at Request.emit (events.js:311:20)
at IncomingMessage. (C:\Users\assas\node_modules\request\request.js:1076:12)
at Object.onceWrapper (events.js:417:28)
at IncomingMessage.emit (events.js:323:22)
at endReadableNT (_stream_readable.js:1204:12)

Are you sure that it should be a dev dependency?

The readme saying that the package can be installed via:
npm i -D fast-average-color.
Actually, it will mark the dependency as a "development". But it seems that the package is for production, likely.

Btw, thanks for the lib

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.