[Android / Glide] 이미지 URL을 읽어 JPG 포맷파일로 변환하기
1. remote url의 이미지를 비트맵 형식으로 가져온다.
1 | fun loadBitmapImage(context: Context, url: String?, listener: RequestListener<Bitmap?>?) { |
Glide를 사용해 listener를 통해 onResourceReady에서 비트맵 리소스를 받아 처리한다.
Glide를 쓰지 않고 가령, 갤러리에 저장된 이미지를 가져와 3번으로 넘어갈 경우, imageView에 비트맵을 저장하게 되는데, 이때 Bitmap의 recycle state를 관리해줘야할 수 있다. (참고: Glide에서 비트맵 이미지가 GC되는 과정)
이런 이유로 Android Developer 공식 문서에서는대부분의 경우 Glide 라이브러리를 사용하여 앱에서 비트맵을 가져오고 디코딩하고 표시하는 것을 추천
한다고 나와있다.
2. 비트맵을 JPG 포맷으로 압축, 저장한다.
- Bitmap.compress 명세
- 참고 Bitmap 컨트롤하기
이제 받아온 비트맵을 remoteTemp.jpg 라는 이름의 파일에 JPG 포맷으로 저장할 것이다.
1 | mRemoteImageUri = Uri.fromFile(getReviewTempImageFile(context |
먼저 저장할 파일의 Uri를 만들었다. Uri를 생성하는 이유는 3번에서 파일의 사이즈를 얻어오기 위함이다. 자세히는 해당 번호 참조.
compress의 두 번째 인자값은 CompressFormat에 대한 압축률이며 0(minimum) ~ 100(maximum)으로 설정할 수 있다.
bitmap.compress(CompressFormat.PNG, 0, filestream)
위와 같이 PNG로 압축하여 출력할 경우 두 번째 인자값은 무시한다. PNG 파일의 특성이 손실률 없는 포맷에 해당하기 때문이다.
위의 코드에서는 FileOutputStream 객체를 사용하여 JPG로 압축한 비트맵이 파일에 저장되었으나 이를 파일로 저장하지 않고 처리하려면 ByteArrayOutputStream를 사용할 수 있다.
- 코드 세부사항 파일에 저장하는 코드 상에서 사용한 getReviewTempImageFile 메소드는 아래와 같다. 여기서 ‣ 주의할 것. getExternalFilesDir()을 사용하기 때문에 미리 WRITE_EXTERNAL_STORAGE 퍼미션 처리를 해주어야 한다. crop을 수행하는 Activity에 진입하기 전에 체크해주는 게 가장 좋다. 해당 퍼미션을 체크하는 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public static File getReviewTempImageFile(Context context, String imageName) {
String imgDirName = "/TestDir";
String dirPath = context.getExternalFilesDir(null) + imgDirName;
File saveDir = new File(dirPath);
if (!saveDir.exists()) {
saveDir.mkdir();
}
String nomediaFilePath = dirPath + "/.nomedia";
File nomediaFile = new File(nomediaFilePath);
if (!nomediaFile.exists()) {
try {
nomediaFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
String filePath = dirPath + "/" + imageName;
return new File(filePath);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28private void doImageSearch() {
if (permissionCheck(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// start CropActivity
} else {
mRequestPermission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
requestPermission(this, PermissionConstants.REQUEST_STORAGE_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
public static boolean permissionCheck(Context context, String permission) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
}
public static void requestPermission(Context context, int requestCode, String permission) {
//shouldShowRequestPermissionRationale - 사용자가 권한 요청을 한번 거절 했을 경우 True
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) {
try {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.parse("package:" + context.getPackageName()));
((Activity) context).startActivityForResult(intent, PermissionConstants.REQ_CODE_REQUEST_SETTING);
} catch (ActivityNotFoundException e) {}
} else {
// 처음 권한 요청 및 다시 보지 않기를 선택하였을 경우 false
ActivityCompat.requestPermissions((Activity) context, new String[]{permission}, requestCode);
}
}
3. 이미지 파일을 적절한 사이즈로 변경하여 재저장
crop을 준비하기 위해서는 디바이스의 한 화면에 적절한 크기로 이미지를 노출해야한다. 위의 코드에서 setPickedImage 메소드가 이 기능을 담당한다.
1 | private void setPickedImage( Uri rawBitmap){ |
[Android / Glide] 이미지 URL을 읽어 JPG 포맷파일로 변환하기
https://dl137584.github.io/2022/02/05/011-convert-remote-url-to-jpg-file/