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

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



답변

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를 확인하십시오 .


답변

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

색 도둑

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

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


답변

“지배 색상”은 까다 롭습니다. 원하는 것은 각 픽셀과 색상 공간의 다른 모든 픽셀 사이의 거리 (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로 변환하는 알고리즘을 찾지 못했습니다.

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


답변

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

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

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


답변

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 코드로 다시 변환 할 수 있습니다.


답변

나는 최근 이미지에서 지배적 인 색상을 얻는 것과 관련하여 원래 https://github.com/briangonzalez/jquery.adaptive-backgrounds.js 를 원했던 jQuery 플러그인을 발견했습니다 .


답변

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