2017-04-15 6 views
1

java에서 일부 저수준 필터를 구현하려고합니다. 이를 위해서는 이미지의 모든 개별 픽셀을 조작 할 수 있어야합니다. 그리고 가장 좋은 방법은 이미지를 바이트 배열로 변환하고 거기에서부터 이동하는 것이라고 생각했습니다.BufferedImage 바이트 배열 조작이 인접한 픽셀에 영향을 미침

4 개의 완전한 빨간색 픽셀로 구성된 2x2 이미지를 만들었습니다. 그럼 내가 배열로 읽어 다음 코드를 사용하여 상당히 정확한 표현을 가지고있어 :

BufferedImage bufferedImage = null; 
try { 
    bufferedImage = ImageIO.read(new File("image.jpeg")); 
} catch (IOException e) { } 

byte[] b = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); 

이것은 제대로 작동합니다. 나는 배열에서이 독서를 얻는다.

0 0 -2 0 0 -2 0 0 -2 0 0 -2 

각 픽셀의 RGB 채널입니다. 어떤 이유로 든 역순으로 인쇄됩니다. B, G, R. 빨간색 채널의 바이트가 -2이므로 픽셀이 빨간색임을 알 수 있습니다. (따라서 부호없는 값은 254 임).

배열의 이러한 픽셀 값을 변경 한 다음 해당 배열을 이미지로 다시 변환하려고하면 문제가 발생합니다. 이 코드를 사용하여 변환을위한

-1 -1 -1 0 0 -2 0 0 -2 0 0 -2 

을 : 예를 들어, I는 백색 제 1 화소를 변경

ImageIO.write(bufferedImage, "jpg", new File("new_image.jpg")); 

그러나 이는 또한 인접 화소에 영향을 미친다. 그냥 첫 번째 픽셀을 흰색으로 설정해야합니다. 비교를 위해 두 개의 이미지가 있습니다.

Processed image

*

Original image

는 하단 모서리에 점선 사각형을 상관하지 않습니다. 내가 스크린 샷을 찍을 때 그것이 어디에서 왔는지 나는 모른다.

답변

2

(OP 대신 게시 됨).

JPEG는 손실이 많은 형식이며 항상 (100 % 품질로) 압축하여 이미지를 일부 손실합니다. .bpm 또는 .png를 사용하면이 효과가 없으며 정상적으로 작동합니다.

+0

주어진 이미지를 제공해서는 안되며, 여기에서 다른 일이 발생합니다. –

+0

@Jean : 그것은 OP가 게시 한 솔루션이었습니다. 이제 방금 위키의 대답으로 옮겼습니다. 아마도 질문에 따라 핑 (ping)합니까? – halfer

+1

그 대답은 정확합니다, 나는 너무 많이 생각하지 않았습니다 ... 물론 이것은 손실 압축 때문입니다. 미안 해요. –