2014-12-13 3 views
3

그래서 화산이있는 이미지 파일이 있습니다. 그 밖의 모든 것은 0xFFFF00FF (불투명 한 마젠타)입니다. 그 색상이 들어있는 모든 픽셀을 0 (투명)으로 바꾸려고합니다. 지금까지 내 방법은 다음과 같습니다.BufferedImage에서 다른 색상으로 색상을 대체하는 방법

public static BufferedImage replace(BufferedImage image, int target, int preferred) { 
    int width = image.getWidth(); 
    int height = image.getHeight(); 
    BufferedImage newImage = new BufferedImage(width, height, image.getType()); 
    int color; 

    for (int i = 0; i < width; i++) { 
     for (int j = 0; j < height; j++) { 
      color = image.getRGB(i, j); 
      if (color == target) { 
       newImage.setRGB(i, j, preferred); 
      } 
      else { 
       newImage.setRGB(i, j, color); 
      } 
     } 
    } 

    return newImage; 
} 

이 작업은 정상적으로 작동하지만 매우 느립니다. 나는 누군가가 이것을 다른 방식으로하는 것을 보았지만, 무슨 일이 일어나고 있는지 전혀 모른다. 누군가가 이것을하는 더 좋은 방법을 안다면, 나는 그것을 아주 듣고 싶습니다.

답변

3

픽셀을 반복하지 않으려면 기본 ColorModel을 변경하십시오. Here이 그 예입니다. 아래는 제작자가 원본 BufferedImage를 가져 와서 새 색상 모델을 적용하는 스 니펫입니다.

private static BufferedImage createImage() { 
    int width = 200; 
    int height = 200; 
    // Generate the source pixels for our image 
    // Lets just keep it to a simple blank image for now 

    byte[] pixels = new byte[width * height]; 
    DataBuffer dataBuffer = new DataBufferByte(pixels, width*height, 0); 
    SampleModel sampleModel = new SinglePixelPackedSampleModel(
    DataBuffer.TYPE_BYTE, width, height, new int[] {(byte)0xf}); 
    WritableRaster raster = Raster.createWritableRaster(
    sampleModel, dataBuffer, null); 
    return new BufferedImage(createColorModel(0), raster, false, null); 
} 

private static ColorModel createColorModel(int n) { 
    // Create a simple color model with all values mapping to 
    // a single shade of gray 
    // nb. this could be improved by reusing the byte arrays 

    byte[] r = new byte[16]; 
    byte[] g = new byte[16]; 
    byte[] b = new byte[16]; 
    for (int i = 0; i < r.length; i++) { 
     r[i] = (byte) n; 
     g[i] = (byte) n; 
     b[i] = (byte) n; 
    } 
    return new IndexColorModel(4, 16, r, g, b); 
} 

private BufferedImage image = createImage(); 
image = new BufferedImage(createColorModel(e.getX()), image.getRaster(), false, null); 
+0

당신은 대답 링크에서 releveant 코드를 추가해야합니다. – Magnilex

+1

이 예제는 모든 색상을 회색으로 매핑하는 IndexColorModel을 사용합니다. 한 색상을 다른 색상으로 바꾸려면 색상 모델을 어떻게 사용해야합니까? – Thayne

0

당신은 setRGB()

을 사용하여 이상이 약간의 속도까지 그래서

for (int i = 0; i < width; i++) { 
    for (int j = 0; j < height; j++) { 
     color = pixels[y * width + x]; 
     if (color == target) { 
      pixels[y * width + x] = preferred; 
     } 
     else { 
      pixels[y * width + x] = color; 
     } 
    } 
} 

처럼 색상을 설정 한 후 너무

int[] pixels = ((DataBufferInt) newImg().getDataBuffer()).getData(); 

같은 버퍼 이미지의 pixels[] 배열을 얻을 수 있습니다

3

나는 아직 완전히 철저히 시험 할 기회가 없었지만, LookupOp 잘 가속 혜택을 누릴 수 있습니다

public class ColorMapper 
extends LookupTable { 

    private final int[] from; 
    private final int[] to; 

    public ColorMapper(Color from, 
         Color to) { 
     super(0, 4); 

     this.from = new int[] { 
      from.getRed(), 
      from.getGreen(), 
      from.getBlue(), 
      from.getAlpha(), 
     }; 
     this.to = new int[] { 
      to.getRed(), 
      to.getGreen(), 
      to.getBlue(), 
      to.getAlpha(), 
     }; 
    } 

    @Override 
    public int[] lookupPixel(int[] src, 
          int[] dest) { 
     if (dest == null) { 
      dest = new int[src.length]; 
     } 

     int[] newColor = (Arrays.equals(src, from) ? to : src); 
     System.arraycopy(newColor, 0, dest, 0, newColor.length); 

     return dest; 
    } 
} 

을 그것이 LookupOp가를 만드는 것만 큼 쉽게 사용 :

Color from = Color.decode("#ff00ff"); 
Color to = new Color(0, true); 
BufferedImageOp lookup = new LookupOp(new ColorMapper(from, to), null); 
BufferedImage convertedImage = lookup.filter(image, null); 
관련 문제