해상도가 다양한 안드로이드는 배너영역의 이미지를 폰별로 최적화 하기는 힘들다. 그래서 고안된것이 디바이스별로 다양한 배너이미지를 만들어 폰 해상도에 따라 최적화된 이미지를 내려주는 방법(애드몹)도 쓰지만 정확하게 맞추기는 힘들고 관리하기도 힘들다.
이런 문제점을 안드로이드의 나인패치기능을 통해 조금이라도 해결가능하다. 예를들면 다음과 같은 결과를 얻을 수 있다.
원본 광고
나인패치(양옆으로만 늘리기)
나인패치(4개의 영역으로 균등하기 늘리기)
* 공고이미지는 저랑 아무런 관계가 없으며 예시를 위해 사용된것뿐임.
직접 구현하기
안드로이드의 나인패치 이미지를 내부 리소스뿐만 아니라 외부이미지에 대해서도 적용이 가능하다. 외부이미지인 즉, 앱 내부에 리소스가 아닌 웹URL을 통해 가져온 이미지나 폰 내부에 있는 이미지도 나인패치를 체크해서 NinePatchDrawable로 만들 수 있다.
안드로이드 소소코드에서 Bitmap.java를 보면 decodeFile()메서드에서 나인패치영역을 저장하고 있으며, getNinePatchChunk()메서드를 통해서 나인패치가 적용된 이미지인지를 확인 할 수 있다.
그렇기 때문에 getNinePatchChunk()에 값이 있다면, Bitmap을 NinePathDrawable로 사용하여 나인패치가 적용가능하다.
다음은 decodeFile()메서드 내부에 나인패치영역을 가져오는 loadNinePatchChunk()메서드이다. png파일을 체크 후 나인패치영역을 bytep[]로 변환해 주도록 구현되어 있다.
private static final byte[] loadNinePatchChunk(String name) {
InputStream stream = name.getClass().getResourceAsStream(name);
if (stream == null) {
return null;
}
try {
IntReader reader = new IntReader(stream, true);
// check PNG signature
if (reader.readInt() != 0x89504e47 || reader.readInt() != 0x0D0A1A0A) {
return null;
}
while (true) {
int size = reader.readInt();
int type = reader.readInt();
// check for nine patch chunk type (npTc)
if (type != 0x6E705463) {
reader.skip(size + 4/* crc */);
continue;
}
return reader.readByteArray(size);
}
} catch (IOException e) {
return null;
}
}
NinePatchDrawable의 생성자를 보면 byte[] chunk가 있는데, Bitmap의 loadNinePatchChunk()메서드에서 가져온 chunk를 넘기면 나인패치이미지로 변환된다.
InputStream stream = .. //whatever Bitmap bitmap = BitmapFactory.decodeStream(stream); byte[] chunk = bitmap.getNinePatchChunk(); boolean result = NinePatch.isNinePatchChunk(chunk); NinePatchDrawable patchy = new NinePatchDrawable(bitmap, chunk, new Rect(), null);
위와 같은 코드를 통해 Bitmap이미지에서 NinePatchDrawable로 변형하여 나인패치가 적용된 이미지를 사용 할 수 있게 된다.
*주의할점은 외부 이미지는 컴파일된 파일이어야 한다. 컴파일 방법은 http://forum.xda-developers.com/showthread.php?t=785012 를 참고하자.
'안드로이드 개발' 카테고리의 다른 글
| Eclipse, IntelliJ에서 Live Templates를 이용한 빠른 레이아웃 구성 (0) | 2014.04.24 |
|---|---|
| AutoCompleteTextView에서 FilterQueryProvider를 이용한 DB쿼리 (0) | 2014.03.03 |
| DB Query를 별도의 Thread로 처리하기 (0) | 2014.01.22 |