Javascript를 통해 이미지의 평균 색상 얻기


118

이것이 가능한지 확실하지 않지만 이미지 의 평균 hex또는 rgb값을 반환하는 스크립트를 작성 하려고합니다. 나는 그것이 AS에서 할 수 있다는 것을 알고 있지만 JavaScript에서 그것을 찾고 있습니다.


19
내 친구 Boaz는 이전에이 길을 걸어 왔지만 (잘하면 그는 차임) 평균적으로 구토와 같은 색을 띕니다. 당신이 정말로 원하는 것은 "우세 색상"입니다. 이를 얻을 수있는 몇 가지 방법이 있지만 (동적 버킷 팅이 포함 된 색조 히스토그램 등) 의도 한 결과에 더 정확하다고 생각합니다.
Paul Irish

답변:


149

AFAIK,이 작업을 수행하는 유일한 방법은 <canvas/>...

데모 V2 : http://jsfiddle.net/xLF38/818/

이는 동일한 도메인의 이미지와 HTML5 캔버스를 지원하는 브라우저에서만 작동합니다.

function getAverageRGB(imgEl) {

    var blockSize = 5, // only visit every 5 pixels
        defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs
        canvas = document.createElement('canvas'),
        context = canvas.getContext && canvas.getContext('2d'),
        data, width, height,
        i = -4,
        length,
        rgb = {r:0,g:0,b:0},
        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 defaultRGB;
    }

    length = data.data.length;

    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);

    return rgb;

}

IE의 경우 excanvas를 확인하십시오 .


1
다른 도메인에있는 이미지의 색상 히스토그램을 얻을 수있는 방법이 있습니까?
Dan Loewenherz 2010 년

1
Dan : 다른 도메인의 이미지에있는 이미지 데이터에 액세스하려고하면 교차 출처 제한에 부딪힌 것 같습니다. 안타까운 일입니다.

8
나는 파란색과 녹색 값에 대한 배치가 있다고 생각 'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'합니다 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'. 주된 색상이 파란색이지만 결과가 녹색이면 이상합니다. :).
Ariona Rian 2013 년

7
출처 간 제한에 대한 훌륭한 해결 방법을 찾았습니다 . 속성을 img.crossOrigin = '';설정하기 전에 추가하십시오 src. 찾은 위치 : coderwall.com/p/pa-2uw
mhu

필요가 있기 때문에, 카운트 없습니다 count === length / 4 / blockSize)
yckart을

84

최근에 우세한 색상을 얻기 위해 찾은 프로젝트를 게시 할 것이라고 생각했습니다.

색 도둑

이미지에서 주요 색상 또는 대표 색상 팔레트를 가져 오는 스크립트입니다. 자바 스크립트와 캔버스를 사용합니다.

지배적 인 색상을 언급하고 제안하는 다른 솔루션은 적절한 컨텍스트 ( "자바 스크립트")에서 질문에 실제로 답하지 않습니다. 이 프로젝트가 그렇게하고 싶은 사람들에게 도움이되기를 바랍니다.


55

"지배 색상"은 까다 롭습니다. 원하는 것은 각 픽셀과 색상 공간의 다른 모든 픽셀 사이의 거리 (Euclidean Distance)를 비교 한 다음 색상이 다른 모든 색상과 가장 가까운 픽셀을 찾는 것입니다. 그 픽셀이 지배적 인 색상입니다. 평균 색상은 일반적으로 진흙입니다.

Euclidean Distance를 보여주기 위해 여기에 MathML이 있었으면 좋겠습니다. Google it.

여기에서 PHP / GD를 사용하여 RGB 색상 공간에서 위의 실행을 수행했습니다. https://gist.github.com/cf23f8bddb307ad4abd8

그러나 이것은 계산적으로 매우 비쌉니다. 큰 이미지에서 시스템이 충돌하고 클라이언트에서 시도하면 브라우저가 확실히 충돌합니다. 내 실행을 리팩토링하여 다음 작업을 수행했습니다.-각 픽셀에 대한 반복에서 나중에 사용할 수 있도록 검색 테이블에 결과를 저장합니다. -큰 이미지를 지역화 된 우위를 위해 20px 20px의 격자로 나눕니다. -x1y1과 x1y2 사이의 유클리드 거리를 사용하여 x1y1과 x1y3 사이의 거리를 알아냅니다.

이 일에 진전이 있으면 알려주세요. 나는 그것을보고 기쁠 것이다. 나도 그렇게 할거야.

Canvas는 클라이언트에서이 작업을 수행하는 가장 좋은 방법입니다. SVG는 그렇지 않고 SVG는 벡터 기반입니다. 실행을 종료 한 후 다음으로 할 일은 캔버스에서 실행하는 것입니다 (아마도 각 픽셀의 전체 거리 계산을 위해 웹 워커와 함께).

고려해야 할 또 다른 점은 RGB 공간에서 색상 간의 유클리드 거리가 시각적 거리에 그리 가깝지 않기 때문에 RGB가이 작업을 수행하기에 좋은 색상 공간이 아니라는 것입니다. 이 작업을 수행하기위한 더 나은 색 공간은 LUV 일 수 있지만 이에 대한 좋은 라이브러리 나 RGB를 LUV로 변환하는 알고리즘을 찾지 못했습니다.

완전히 다른 접근 방식은 무지개에서 색상을 정렬하고 다양한 색상 음영을 고려하여 허용 오차가있는 히스토그램을 만드는 것입니다. 무지개에서 색상을 정렬하는 것이 어렵고 색상 히스토그램도 어렵 기 때문에 이것을 시도하지 않았습니다. 다음에 시도해 볼게요. 여기서도 진전이 있으면 알려주세요.


6
이것은 내가 그냥 +1 :-)보다 더 많은 일을 할 수 있으면 좋겠다있는 그 해답 중 하나입니다
데이비드 존스톤

3
명확한 솔루션이 렌더링되지 않았지만 훌륭한 답변입니다. 이것은 제가 다음 단계를 결정하는 데 도움이 될 것입니다.
bgreater

이것은 좋은 대답입니다. LUV가 아니라 L a b * 색 공간 에서 유클리드 거리 계산을 수행하기 위해 몇 개의 노드 모듈을 작성했습니다 . 참조 github.com/zeke/color-namergithub.com/zeke/euclidean-distance
지크

1
@user : 나는 단지 궁금했다 : 1 % 샘플이 큰 이미지에서 계산 속도를 높이기에 충분하지 않을까요?
jackthehipster

기하학적 중앙값처럼 들립니다. 도움이 될까요? stackoverflow.com/questions/12934213/… 찾고있는 포인트 가 원래 세트 에 있어야 하는 경우 : en.m.wikipedia.org/wiki/Medoid#Algorithms_to_compute_medoids
Lawrence Weru

16

첫째 : HTML5 Canvas 또는 SVG없이 수행 할 수 있습니다.
사실, 사람은 관리 자바 스크립트를 사용하여 클라이언트 측 PNG 파일 생성 , 없는 사용하여 캔버스 또는 SVG를 데이터 URI 체계를 .

둘째 : 실제로 Canvas, SVG 또는 위의 어떤 것도 필요하지 않을 수 있습니다.
당신은 단지에 필요한 경우 프로세스 클라이언트 측 이미지 없이 수정 에는이 모든 것이 필요하지 않습니다.

페이지의 img 태그에서 소스 주소를 가져 와서 XHR 요청을 할 수 있습니다 (대부분 브라우저 캐시에서 올 것입니다). 그리고이를 Javascript에서 바이트 스트림으로 처리합니다.
이미지 형식을 잘 이해해야합니다. (위의 생성기는 부분적으로 libpng 소스를 기반으로하며 좋은 시작점을 제공 할 수 있습니다.)


바이트 스트림 솔루션의 경우 +1. 유일한 옵션이 클라이언트 응용 프로그램에서 만드는 것이라면 좋은 방법입니다.
loretoparisi

11

HTML 캔버스 태그를 통해 말할 것입니다.

여기 @Georg가 Opera dev의 작은 코드에 대해 이야기하는 게시물을 찾을 수 있습니다 .

// Get the CanvasPixelArray from the given coordinates and dimensions.
var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

// Loop over each pixel and invert the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i  ] = 255 - pix[i  ]; // red
    pix[i+1] = 255 - pix[i+1]; // green
    pix[i+2] = 255 - pix[i+2]; // blue
    // i+3 is alpha (the fourth element)
}

// Draw the ImageData at the given (x,y) coordinates.
context.putImageData(imgd, x, y);

이것은 각 픽셀의 R, G 및 B 값을 사용하여 이미지를 반전시킵니다. RGB 값을 쉽게 저장 한 다음 Red, Green 및 Blue 배열을 반올림하고 마지막으로 HEX 코드로 다시 변환 할 수 있습니다.


캔버스 솔루션에 대한 IE 대안이 있습니까?
bgreater

@ Ben4Himv : IE9 플랫폼 미리보기가 있습니다 ;-) 그러나 진지하게, 나는 두려워하지 않습니다.
Andy E


4

자바 스크립트는 이미지의 개별 픽셀 색상 데이터에 액세스 할 수 없습니다. 적어도 html5가 될 때까지는 ...이 시점에서 캔버스에 이미지를 그린 다음 캔버스를 검사 할 수있을 것이라고 생각합니다 (아마도 제가 직접 해본 적이 없습니다).


2

올인원 솔루션

저는 개인적으로 Color ThiefName that Color 의 수정 된 버전을 결합하여 이미지에 대한 지배적 인 색상 결과를 더 많이 얻습니다.

예:

다음 이미지를 고려하십시오.

여기에 이미지 설명 입력

다음 코드를 사용하여 주요 색상과 관련된 이미지 데이터를 추출 할 수 있습니다.

let color_thief = new ColorThief();
let sample_image = new Image();

sample_image.onload = () => {
  let result = ntc.name('#' + color_thief.getColor(sample_image).map(x => {
    const hex = x.toString(16);
    return hex.length === 1 ? '0' + hex : hex;
    
  }).join(''));
  
  console.log(result[0]); // #f0c420     : Dominant HEX/RGB value of closest match
  console.log(result[1]); // Moon Yellow : Dominant specific color name of closest match
  console.log(result[2]); // #ffff00     : Dominant HEX/RGB value of shade of closest match
  console.log(result[3]); // Yellow      : Dominant color name of shade of closest match
  console.log(result[4]); // false       : True if exact color match
};

sample_image.crossOrigin = 'anonymous';
sample_image.src = document.getElementById('sample-image').src;

1

이것은 MMCQ (Modified Median Cut Quantization) 또는 OQ (Octree Quantization) 와 같은 몇 가지 접근 방식이있는 "Color Quantization"에 관한 것 입니다. 다른 접근법은 K- 평균 을 사용하여 색상 클러스터를 얻습니다.

요소 tvOS가없는 XHTML의 하위 집합이있는 곳에 대한 솔루션을 찾고 있었기 때문에 여기에 모두 정리했습니다 <canvas/>.

XMLHttpRequest를 사용하여 RGB 이미지에 대한 주요 색상 생성


1

덜 정확하지만 datauri지원 을 통해 이미지의 평균 색상을 얻는 가장 빠른 방법 :

function get_average_rgb(img) {
    var context = document.createElement('canvas').getContext('2d');
    if (typeof img == 'string') {
        var src = img;
        img = new Image;
        img.setAttribute('crossOrigin', ''); 
        img.src = src;
    }
    context.imageSmoothingEnabled = true;
    context.drawImage(img, 0, 0, 1, 1);
    return context.getImageData(1, 1, 1, 1).data.slice(0,3);
}

1

다른 답변에서 지적했듯이 종종 갈색 경향이있는 평균 색상과 달리 지배적 인 색상을 원하는 경우가 종종 있습니다. 가장 일반적인 색상을 얻는 스크립트를 작성하여이 요점 에 게시했습니다.


-2

이미지 의 평균 또는 주요 색상을 찾는 데 도움 이되는 온라인 도구 인 pickimagecolor.com 이 있습니다. 컴퓨터에서 이미지를 업로드 한 다음 이미지를 클릭하기 만하면됩니다. HEX, RGB 및 HSV의 평균 색상을 제공합니다. 또한 선택할 해당 색상과 일치하는 색상 음영을 찾습니다. 나는 그것을 여러 번 사용했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.