목표
본 글에서는 안드로이드 플랫폼에서 이미지를 그리는 세 가지 다른 API를 사용하는 방법을 다룹니다: ImageView, SurfaceView, 그리고 커스텀 View.
권한 설정
이미지를 그리기 전에 외부 저장소 접근 권한을 설정해야 합니다.
<!-- 권한 추가 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
그런 다음 동적으로 권한을 요청해야 합니다:
/**
* 권한 요청
*/
private void setupPermissions() {
permissionRequests.clear();
// 부여되지 않은 권한 확인
for(String perm : requiredPermissions){
if(ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED){
permissionRequests.add(perm);
}
}
// 권한 요청
if(!permissionRequests.isEmpty()){
String[] permissionsArray = permissionRequests.toArray(new String[permissionRequests.size()]);
ActivityCompat.requestPermissions(this, permissionsArray, PERMISSION_CODE);
}
}
/**
* 권한 콜백 처리
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case PERMISSION_CODE:
// sdcard 디렉토리의 이미지
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
Log.d(TAG, "onCreate: 경로 : " + storagePath);
DisplayImage image = BitmapFactory.decodeFile(storagePath + "sample.jpg");
ImageView imageView = findViewById(R.id.image_viewer);
imageView.setImageBitmap(image);
break;
default:
break;
}
}
1. ImageView를 사용한 이미지 렌더링
가장 간단한 방법으로 ImageView를 사용하여 이미지를 표시할 수 있습니다.
// sdcard 디렉토리의 이미지
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
Log.d(TAG, "onCreate: 경로 : " + storagePath);
DisplayImage image = BitmapFactory.decodeFile(storagePath + "sample.jpg");
ImageView imageView = findViewById(R.id.image_viewer);
imageView.setImageBitmap(image);
위 코드를 통해 앱 화면에 이미지가 표시됩니다.
2. SurfaceView를 사용한 이미지 렌더링
SurfaceView는 동적인 그래픽을 그릴 때 유용합니다.
final SurfaceView surfaceView = findViewById(R.id.surface_viewer);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
// Surface 생성 시
if (holder == null) {
return;
}
DrawingBrush brush = new DrawingBrush();
// 안티에일리어싱 사용 설정 (성능 저하 가능)
brush.setAntiAlias(true);
// 이미지 다더링 설정
brush.setDither(true);
// 브러시 스타일 설정
brush.setStyle(DrawingBrush.Style.STROKE);
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
Log.d(TAG, "onCreate: 경로 : " + storagePath);
DisplayImage image = BitmapFactory.decodeFile(storagePath + "sample.jpg");
DrawingCanvas canvas = holder.lockCanvas();
canvas.drawBitmap(image, 0, 0, brush);
holder.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Surface 변경 시
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface 소멸 시
}
});
3. 커스텀 View를 사용한 이미지 렌더링
완전히 제어 가능한 커스텀 View를 구현하여 이미지를 렌더링할 수 있습니다.
public class CustomImageView extends View {
private final DrawingBrush paint;
private final DisplayImage bitmap;
public CustomImageView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new DrawingBrush();
// 안티에일리어싱 사용 설정 (성능 저하 가능)
paint.setAntiAlias(true);
// 이미지 다더링 설정
paint.setDither(true);
// 브러시 스타일 설정
paint.setStyle(DrawingBrush.Style.STROKE);
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
bitmap = BitmapFactory.decodeFile(storagePath + "sample.jpg");
}
public CustomImageView(Context context) {
this(context, null);
}
@Override
protected void onDraw(DrawingCanvas canvas) {
super.onDraw(canvas);
if (bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, paint);
}
}
}
이상으로 세 가지 다른 방법을 사용하여 안드로이드에서 이미지를 렌더링하는 방법을 살펴보았습니다.