2014-06-14 2 views
2

나는 제품 이미지를 가지고 각 이미지는 다음과 같이 두 가지 구성 영역이있다 : 나는 고객이 두 영역의 색상을 변경하고 저장할 수있는 기능을 개발해야 1. 배경 2. 전경자바 스크립트 캔버스에서 픽셀을 조작

을 디자인.

내 문제는, 나는 이전 픽셀 값을 읽고 새 선택된 색상으로 이미지를 변경하려고합니다.

비트 오래된 픽셀 값이 일치하지 않습니다. 이미지에 질감 효과가있어 모든 픽셀에서 픽셀 값이 변경됩니다.

원하는 기능을 어떻게 얻을 수 있습니까?

또는 다른 방법을 제안 할 수 있다면 좋을 것입니다.

샘플 이미지 링크 : http://developersbench.com/canvas/img/design_2.jpg

+0

예상 출력/시도한 내용에 대해 자세히 설명해 주시겠습니까? 바이올린을 제공하는 것은 좋지만, 외국 사이트에서로드 된 이미지의 데이터를 읽을 때 교차 출처 문제가있을 수 있습니다. – GameAlchemist

답변

1

내가 잘 생각하면, 당신이 원하는 것은 주어진 색상 '근처'있는 픽셀을 변경하는 것입니다 다른 색상으로 변경할 수 있습니다.

내가보기에 가장 쉬운 방법은 h, s, l 색 공간을 사용하는 것입니다.이 '자연스러운'색 공간에서 비슷한 색조를 갖는 색은 눈으로 비슷하게 감지됩니다. 그리고 동일한 채도 (= 색상 '강도')와 밝기를 유지하면서 색조를 '이동'시킬 수 있습니다.

그래서 포인트 이미지 포인트를 처리 : 색조, 채도에 B
• 변환 포인트 R, G, 밝기
•를? 현재 색조가 sourceHue에서 충분히 가깝습니까?
는 ---- >> newHue (유지 동일 채도/밝기)로 이동

바이올린 여기 :

http://jsfiddle.net/9GLNP/

하면 매개 변수들을 플레이 할 수있다. 입력 한 텍스처의 평균 색상이 18입니다. 따라서 소스 색상이 18에서 너무 멀면 변경되지 않습니다. 8-10은 좋은 관용처럼 보입니다.

enter image description here

// Provides a new canvas containing [img] where 
// all pixels having a hue less than [tolerance] 
// distant from [tgtHue] will be replaced by [newHue] 
function shiftHue(img, tgtHue, newHue, tolerance) { 
    // normalize inputs 
    var normalizedTargetHue = tgtHue/360; 
    var normalizedNewHue = newHue/360; 
    var normalizedTolerance = tolerance/360; 
    // create output canvas 
    var cv2 = document.createElement('canvas'); 
    cv2.width = img.width; 
    cv2.height = img.height; 
    var ctx2 = cv2.getContext('2d'); 
    ctx2.drawImage(img, 0, 0); 
    // get canvad img data 
    var imgData = ctx2.getImageData(0, 0, img.width, img.height); 
    var data = imgData.data; 
    var lastIndex = img.width * img.height * 4; 
    var rgb = [0, 0, 0]; 
    var hsv = [0.0, 0.0, 0.0]; 
    // loop on all pixels 
    for (var i = 0; i < lastIndex; i += 4) { 
     // retrieve r,g,b (! ignoring alpha !) 
     var r = data[i]; 
     var g = data[i + 1]; 
     var b = data[i + 2]; 
     // convert to hsv 
     RGB2HSV(r, g, b, hsv); 
     // change color if hue near enough from tgtHue 
     var hueDelta = hsv[0] - normalizedTargetHue; 
     if (Math.abs(hueDelta) < normalizedTolerance) { 
      // adjust hue 
      // ??? or do not add the delta ??? 
      hsv[0] = normalizedNewHue //+ hueDelta; 
      // convert back to rgb 
      hsvToRgb(rgb, hsv); 
      // store 
      data[i] = rgb[0]; 
      data[i + 1] = rgb[1]; 
      data[i + 2] = rgb[2]; 
     } 
    } 
    ctx2.putImageData(imgData, 0, 0); 
    return cv2; 
} 

편집 : 는 색조를 얻기 위해, 나는 색상을 consoled.log ...;-)하지만 많은 경우 (모두는 아니지만) 이미지 소프트웨어에는 hsl을 보여주는 색상 선택 도구가 있습니다.
hsl의 경우 구체적인 링크가 없습니다. google 그것도 그래픽 소프트웨어 내에서 로 재생할 수 있습니다.
코딩 악몽을 피하기 위해, 당신이 사용하는 질감에 컨벤션을 결정해야 할 것 같아요, 그들은 60 +/- 5 색조 등입니다. 그럼 당신은 만 게임의 최종 색조를 결정해야합니다. 탐지가 까다로울 수 있습니다.

+0

안녕하세요, 세부적인 코드를 보내 주셔서 감사합니다. 시도해 볼게. 예제 이미지에서 흰색 선과 같이 앞면 색을 변경하고 싶습니다. 색조 또는 h, l, i 색상 주위의 링크를 공유 할 수 있습니까? ...) –

+0

"하나의 쿼리에 18 개의 평균 색조가 있습니다." . 당신이이 범위를 어떻게 계산했는지 나는 같은 종류의 그림들을 많이 가지고 있기 때문에, 그것들 모두가 다를 것이라고 확신합니다. 이 변형을 계산할 수 있습니까? –

1

나는 이미 이미지의 RGBA 픽셀 데이터를 얻을 수 context.getImageData을 수행하는 방법을 알고 있으리라 믿고있어.

html5 캔버스가 기본적으로 사용하는 RGBA 형식은 색상을 변경할 때별로 유용하지 않습니다. 시각적으로 비슷한 두 가지 색상은 종종 RGB 값이 매우 다릅니다.

대신이 RGBA 색상을 HSL 형식으로 변환하십시오. HSL의 "H"는 우리가 색상으로 생각하는 "색조"입니다. 비슷한 색상의 픽셀은 비슷한 HSL "색조"값을 갖습니다.

그런 다음 사용자는 기존 색조 값을 일정한 오프셋으로 "이동"하여 이미지를 다시 칠할 수 있습니다.

데모는 : http://jsfiddle.net/m1erickson/326yc/

+0

안녕하세요. 솔루션을 제공해 주셔서 감사합니다. 이 조건에 약간의 빛을 비춰 주시겠습니까? (색조> 200 && 색조 <300) ..... 012- [200-300]에서 다른 색상으로 변경되는 모든 픽셀 값으로 변경 한 것에 따라 그러나 샘플 이미지의 전경색이 같은 범주에 속하면이 코드도 변경됩니다. –

+0

수정. 따라서 배경 및 전경 이미지를 개별적으로 처리하고 처리 된 이미지를 최종 결과로 병합해야합니다. 프로젝트에 행운을 빌어 요! – markE

+0

내가 틀리지 않다면, 나는 같은 크기의 세 가지 다른 이미지를 찍었다 고 생각합니다 : 1) 배경 2) 전경 3) 질감이있는 패턴. 배경/전경에서 다르게 픽셀/색상 조작을해야하며 각 조작 후에 최종 출력을 얻으려면 세 가지 이미지의 픽셀을 결합해야합니다. –

관련 문제