2013-07-18 5 views
0

이미지, 이전 색상의 16 진수 값 및 새 색상의 16 진수 값을 취한 다음 이전 색상의 모든 픽셀을 새로운 색상으로 변환하는 메소드를 작성하려고합니다. 색깔. 현재, if 문이 전혀 작동하지 않는 것처럼,이 메서드는 전체 이미지에 새로운 색을 칠합니다. 이 방법은색상 변환

private void convertColors(BufferedImage img, int oldColor, int newColor) 
{ 
    Graphics g = img.getGraphics(); 
    g.setColor(new Color(newColor)); 
    Color old = new Color(oldColor); 

    for(int x = 0; x < img.getWidth(); x++) 
    { 
     for(int y = 0; y < img.getHeight(); y++) 
     { 
      Color tmp = new Color(img.getRGB(x, y)); 
      if(tmp.equals(old)); 
      { 
       System.out.println("Temp=" + tmp.toString() + "Old=" + old.toString() + "New=" + g.getColor().toString()); 
       g.fillRect(x, y, 1, 1); 
      } 
     } 
    } 
    g.dispose(); 
} 

* oldColor의 진수는 0xFFFFFF (흰색)과 newColor에 대한 0xFF0000 (빨간색)입니다.

나는 결과 이런 종류의 얻을 println 메소드 방법 사용 :

Temp=java.awt.Color[r=0,g=0,b=0]Old=java.awt.Color[r=255,g=255,b=255]New=java.awt.Color[r=255,g=0,b=0] 
Temp=java.awt.Color[r=255,g=255,b=255]Old=java.awt.Color[r=255,g=255,b=255]New=java.awt.Color[r=255,g=0,b=0] 

scond 라인이 올바른 보이는, 임시 색상과 오래된 동일을, 그러나 그것은 분명히 최초의 경우가 아닙니다. 나는 또한 새로운 BufferedImage를 만들고 픽셀을 복사하려고 시도했지만 동일한 결과를 남긴다 ... equals 메서드가 작동하지 않거나 또는이 전체 메서드가 제대로 작동하지 않는다고 생각하고이 작업을 수행하는 더 좋은 방법이 있습니까? 도움을 주셔서 감사합니다.

+0

getRGB를 사용하여 색상을 얻기과 작은 사각형 그리기 -이 특히 게임을 느리게 할 것이다. 빠른 방법은 BufferedImage 뒤에있는 int 배열을 직접 조작 한 다음 변경된 이미지를 한 번에 그려 보는 것입니다. – lbalazscs

+0

@lbalazscs 당신 말이 맞아요, 저는 현재 어떻게 구현하고 rgb 필터를 사용하여 자신의 필요를 채워주고 있습니다. 하지만 그는 이미지의 그래픽을 변경하기 때문에이 함수를 한 번 호출하면 저장된 이미지의 색상이 정확하지 않습니다. – luk2302

+0

@lbalazscs는 I 그렇게하려고하면 경우 (화소 [X + Y의 *의 img.getWidth()] == oldColor) \t \t \t \t { \t \t \t \t \t 화소 [X + Y의 *의 IMG.getWidth()] = newColor; \t \t \t} if 문으로 들어가지만 setRGB를 호출해도 변경 내용이 표시되지 않습니다. newImg.setRGB (0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth()); btw, 무엇 오프셋 및 scansize 무엇입니까? – StrongJoshua

답변

-1

나는 작동하도록했습니다. 이 작업 convertColors 방법입니다 :

private BufferedImage convertColors(BufferedImage img, int oldColor, int newColor) 
{ 
    int [] pixels = new int [img.getWidth() * img.getHeight()]; 
    img.getRGB(0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth()); 
    Color old = new Color(oldColor); 
    Color newC = new Color(newColor); 

    for(int x = 0; x < img.getWidth(); x++) 
    { 
     for(int y = 0; y < img.getHeight(); y++) 
     { 
      Color tmp = new Color(pixels[x + y * img.getWidth()]); 
      if(tmp.equals(old)) 
      { 
       pixels[x + y * img.getWidth()] = newC.getRGB(); 
      } 
     } 
    } 
    img.setRGB(0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth()); 

    return newImg; 
} 
4

if(tmp.equals(old)) 이후에 ;을 제거하면됩니다.
그렇지 않으면 색상을 비교하고 비교 후에 아무 작업도 수행하지 않고 항상 새 색상을 선택합니다.

당신은 당신의 코드를 조금 재구성해야한다는 것이 약간 더 효율적으로 만들 외에 :

Graphics g = img.getGraphics(); 
g.setColor(new Color(newColor)); 

for(int x = 0; x < img.getWidth(); x++) { 
    for(int y = 0; y < img.getHeight(); y++) { 
     if(img.getRGB(x, y) == oldColor) {//check if pixel color matches old color 
      g.fillRect(x, y, 1, 1);//fill the pixel with the right color 
     } 
    } 
} 
g.dispose(); 



를 내가 주제에 관심을해서 : 이미지 필터에 의존하는 것은 당신이 모든 것을 할 수있는 를 통해 :

BufferedImage img;//your image 
ColorSwapFilter filter = new ColorSwapFilter(...,...);//your colors to be swapped. 
ImageProducer producer = img.getSource(); 
producer = new FilteredImageSource(producer, filter); 
Image im = Toolkit.getDefaultToolkit().createImage(producer); 
를 통해 호출 할 필요가

class ColorSwapFilter extends RGBImageFilter { 
    int newColor, oldColor; 
    public ColorSwapFilter(int newColor, int oldColor) { 
    canFilterIndexColorModel = true; 
    this.newColor = newColor; 
    this.oldColor = oldColor; 
    } 

    @Override 
    public int filterRGB(int x, int y, int rgb) { 
    return rgb == oldColor ? newColor : oldColor; 
    } 
} 

+0

나는 그 실수를 너무 많이 반복하고 놀랐다. 나는 여전히 그것을 만든다. 당신의 방법을 사용하여 실제로 어떤 이유로 화이트 픽셀을 빨간색으로 바꾸지 않아서 광산을 사용해야하지만, 부분적으로 빨간 이미지를 또한 그려 낸다. 번호 뒤에. 이 부분을 더 살펴 보겠습니다 만 도움을 주셔서 감사합니다. – StrongJoshua

+0

네 말이 맞아, 내 실수 야. – StrongJoshua

+0

@StrongJoshua 정상적으로는 신경 쓰지 않겠지 만, 대답의 시간이 차이를 만들었다 고 지적한 이후로 나는 그것을 지적해야한다고 느꼈다. btw 나는 심지어 당신이 실제로 "받아 들인 대답"을 바꿀 수 있다는 것을 알지 못했습니다 : O – luk2302

3

당신은 당신의 if(tmp.equals(old));

이 esentially 자바 당신의 문은 그와 관련된 단 하나의 명령을 가지고 있으며, 그 명령을 효과적으로 "아무것도하지 않는"을 의미 하나 세미콜론 인 경우를 말한다 if 문 후 직접 세미콜론이있다. 이 코드를 제거하면 아래에있는 코드 블록의 조건이 복원됩니다.이 코드 블록은 조건에 관계없이 매번 실행됩니다.

+0

당신이 처음 이었으므로 당신은 받아 들여진 대답을 얻었을 것입니다, 그러나 나는 그들 모두를 upvoted했습니다. – StrongJoshua

+0

@StrongJoshua ehhhm, 실제로 나는 처음이었다 ... ^^ – luk2302

+0

@Kon 미안, 너의 점수를 "훔치다", 나는 너에게 다른 곳에서 upvote를 줄 것이다 :) – luk2302