J2ME : 투명한 PNG 이미지를 회색체로 변환합니다
문제
J2ME에 이미지 (알파가있는 PNG 파일에서로드 된)를 새로운 투명한 회색조 이미지로 변환 할 가능성이 있습니까?
지금까지 나는 RGB 값 만 얻었지만 알파는 아닙니다.
감사.
편집 : 예, 32 비트 회색 스케일이어야합니다.
해결책
솔루션을 찾았고 여기에 코드가 있습니다.
public Image getGrayScaleImage() {
int[] rgbData = new int[getWidth() * getHeight()];
image.getRGB(rgbData, 0, getWidth(), 0, 0, getWidth(), getHeight());
for (int x = 0; x < getWidth() * getHeight(); x++) {
rgbData[x] = getGrayScale(rgbData[x]);
}
Image grayImage = Image.createRGBImage(rgbData, getWidth(), getHeight(), true);
return grayImage;
}
private int getGrayScale(int c) {
int[] p = new int[4];
p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
p[3] = (int) (c & 0x000000FF); // Blue level
int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
// a little bit brighter
nc = nc / 2 + 127;
p[1] = nc;
p[2] = nc;
p[3] = nc;
int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
return gc;
}
getRGB는 알파 채널도 포함 된 색상 값을 반환합니다. 그래서 나는 배열의 각 값을 변경하고 그로부터 이미지를 만들어야했습니다.
노키아 포럼에서 유용한 문서를 찾았습니다. MIDP 2.0 : 픽셀 및 DrawRGB ()로 작업
다른 팁
Greyscale로 변환하는 코드에 감사드립니다. 그러나 Nokia Series 40 장치 에서이 코드는 오히려 느리게 실행된다는 것을 알았습니다.
2 개의 최적화가 있습니다. 주요 것은 getGrayscale ()에서 객체 생성을 제거하는 것입니다. 현재 모든 픽셀마다 배열 객체가 생성됩니다. 평균적으로 QVGA는 76800 배열 개체 인 디스플레이가 생성되어 많은 쓰레기이며 아마도 GC를 호출 할 것입니다. 클래스의 필드로 int [4]를 정의하면이 객체 생성이 제거됩니다. 여기에서 트레이드 오프는 수업에 사용되는 소량의 추가 RAM입니다.
두 번째는 너비와 높이를 getGraysCaleImage ()로 캐시하는 것입니다. 일부 장치에서는 getWidth () 및 getheight ()에 대한 메소드 호출이 최적화없이 반복적으로 호출됩니다 (JIT 컴파일러는 괜찮지 만 일부 해석 된 장치는 그렇지 않음). 따라서 다시 QVGA의 경우 getWidth () 및 getheight ()를 그들 사이에서 150000으로 불립니다.
전혀,이 수정 된 버전이 훨씬 빨리 달렸다는 것을 알았습니다 :-)
public Image getGrayScaleImage(Image screenshot) {
int width = getWidth();
int height = getHeight();
int screenSizeInPixels = (width * height);
int[] rgbData = new int[width * height];
image.getRGB(rgbData, 0, width, 0, 0, width, height);
for (int x = 0; x < screenSizeInPixels ; x++) {
rgbData[x] = getGrayScale(rgbData[x]);
}
Image grayImage = Image.createRGBImage(rgbData, width, height, true);
return grayImage;
}
static int[] p = new int[4];
private int getGrayScale(int c) {
p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
p[3] = (int) (c & 0x000000FF); // Blue level
int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
// a little bit brighter
nc = nc / 2 + 127;
p[1] = nc;
p[2] = nc;
p[3] = nc;
int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
return gc;
}
(클래스 데이터 공간을 실제로 사용하고 싶지 않은 경우 int []를 스택에 살아갈 4 개의 별도 로컬 int 변수로 바꾸십시오).