출처: http://javacan.tistory.com/entry/TIP-Get-GLMAXTEXTURESIZE-value-in-android
http://javacan.tistory.com/entry/tip-get-size-of-image-and-resize-in-android
안드로이드의 ImageView에 출력할 수 있는 이미지 크기에 제한이 있는데, 이 제한은 장치마다 다르다.
예를 들어, 넥서스7의 경우는 2048*2048 이내의 이미지를 출력할 수 있고, 갤럭시노트10.1의 경우
4096*4096 이내의 이미지를 출력할 수 있다.
만약 제한 크기를 넘는 이미지를 ImageView를 통해 보여주려고 하면 다음과 비슷한 메시지가 로그에
출력되면서 ImageView에 이미지가 출력되지 않게 된다.
W/OpenGLRenderer(6156): Bitmap too large to be uploaded into a texture (560x6076, max=2048x2048)
ImageView에 표시할 수 있는 이미지의 제한 크기를 알아내려면 OpenGL의 glGetIntegerv() 메서드를
사용하면 된다. 이 메서드를 사용하려면 OpenGL Context를 생성해주어야 하는데, SurfaceView를
이용하면 간단하게 알아낼 수 있다.
다음은 SurfaceView와 OpenGL을 이용해서 제한 크기를 알아내는 코드 예이다.
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.opengles.GL10;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
...
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
LinearLayout layout = (LinearLayout) findViewById(R.id.body);
layout.addView(new GetMaxTextureSizeSurfaceView(this));
}
private void goHome() {
Intent intent = new Intent(this, HomeActivity.class);
startActivity(intent);
finish();
}
class GetMaxtextureSizeSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
public GetSizeSurfaceView(Context context) {
super(context);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
setMaxTextureSize();
goHome();
}
private void setMaxTextureSize() {
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLContext ctx = egl.eglGetCurrentContext();
GL10 gl = (GL10) ctx.getGL();
IntBuffer val = IntBuffer.allocate(1);
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, val);
int size = val.get(); // 최대 크기 구함
Constants.setMaxTextureSize(size); // Constants는 글로벌 변수 저장용
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
}
최초로 실행되는 Activity에서 위와 같이 glGetIntegerv() 함수를 이용해서 최대 크기 값을 글로별 변수에
저장하면, 이후 Activity에서는 글로벌 변수를 이용해서 Bitmap 크기가 최대 크기를 넘어섰는지 확인할 수 있다. 만약 최대 크기를 넘어섰다면 이미지를 허용까지 줄여서 출력하면 된다.
주의할 점은 SurfaceView가 화면에 반드시 보여야 한다는 점이다.
화면에 보이지 않게 되면 관련 콜백 메서드(surfaceCreated() 등)가 호출되지 않는다.
GetSizeSurfaceView는 단순히 최대 크기를 알아내기 위해 만든 것이므로 1px 정도의 크기를 갖는
Layout에 SurfaceView를 추가하는 방법으로 SurfaceView를 생성하면 화면에 영향을 거의 안 주면서 SurfaceView를 이용해서 MAX_TEXTURE_SIZE 값을 구할 수 있을 것이다.
이미지 크기를 알아내고 크기를 변경하는 방법은 아래와 같다.
안드로이드에서 이미지를 ImageView에 출력할 때 발생할 수 있는 문제는 크게 다음의 두 가지가 있다.
이 두 가지 문제를 해소하려면 이미지 크기가 특정 크기를 넘어선 경우 이미지 크기를 줄여서 읽어오면 된다.
|
이 옵션을 이용해서 BitmapFactory의 decode 메서드를 사용한다. 아래는 파일로부터 이미지 크기를
구할 때 사용되는 코드 예를 보여주고 있다.
이미지의 크기만 구해서 옵션에 설정한다. 이 메서드 실행 후, 옵션의
이미지 크기 변경하기
이미지 크기를 변경할 때에는 옵션의 inSampleSize 값을 이용한다.
예를 들어, 아래 코드는 크기를 2배 축소시켜서 Bitmap을 생성해주는 코드이다.
3000*2000 크기의 이미지가 있을 때, inSampleSize 값으로 2를 사용하면 생성되는 Bitmap의 크기는 1500*1000이 된다. inSampleSize의 값을 4로 주면 실제 폭/높이는 1/4로 줄고, 8을 주면 실페 폭/높이는 1/8로 준다. 2의 거듭제곱을 inSampleSize의 값으로 주면 연산이 좀 더 빠르게 처리된다.
- [팁] 안드로이드 GL_MAX_TEXTURE_SIZE 값 구하기:
http://javacan.tistory.com/entry/TIP-Get-GLMAXTEXTURESIZE-value-in-android
'IT_Programming > OpenGL' 카테고리의 다른 글
[펌] 안드로이드 OpenGL ES 2, GLSL 소개 (0) | 2015.02.26 |
---|---|
[펌] OpenGL, Surfaceview 에서 Navigation Drawer, Sliding Menu 구현시 주의사항 & DrawerLayout not working with Android 4.4 & SurfaceView (0) | 2014.03.11 |
Android OpenGL (0) | 2012.08.13 |
[펌] GLSurfaceView 분석 (0) | 2008.12.29 |