본문 바로가기
개발/Android

[안드로이드 앱 개발] 갤러리에서 이미지 선택해 새 파일로 복사하기 (Java)

by 즐거운 개발 인생 2022. 2. 9.
728x90
반응형

[안드로이드 앱 개발] 갤러리에서 이미지 선택해 새 파일로 복사하기 (자바) (이미지 회전 문제 해결됨)
[android app develop] duplicate image from gallery (Java) (duplicated image rotated problem solved)


이미지 또는 gif 파일 가져오기 위해 갤러리앱으로 이동
Go to the gallery app to import image or gif file

private void pickFromGallery(){ //갤러리에서 이미지 선택하기
    Intent intent=new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    String[] mimeTypes = {"image/jpg", "image/jpeg", "image/png"};
    intent.putExtra(Intent.EXTRA_MIME_TYPES,mimeTypes);
    startActivityForResult(intent,PICK_IMAGE);
}

갤러리에서 가지고 온 이미지 Glide를 이용해 화면에 보여주기
display image from gallery on screen using Glide

String saveName = null; //새로 저장할 파일 이름

//갤러리에서 선택한 이미지 파일 데이터 처리
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
        if (data == null) {
            saveName = null;
            return;
        }
        data.getExtras().get("data");
        Uri url = data.getData();

        String[] filePathColumn = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(url, filePathColumn, null, null, null);
        String format = "", filePath = ""; //원본 이미지 형식, 원본 이미지 경로
        String fileName = ""; //원본 이미지 이름
        File file = null; //원본 이미지 파일
        if (cursor.moveToFirst()) {
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            filePath = cursor.getString(columnIndex);
            file = new File(filePath);

            format = filePath.substring(filePath.lastIndexOf(".") + 1);
            fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.lastIndexOf("."));
            saveName = String.format("%s.%s",fileName, format); //새로 저장할 이미지 파일 이름
        }

        try {
            //원본 이미지 bitmap
            bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), url);

            //원본 이미지의 회전 반영한 bitmap
            Bitmap rotatedBitmap = Utils.modifyOrientation(bitmap, file.getAbsolutePath());

            //gif와 이미지 구분해 파일 저장 처리 (Utils.java에서 처리)
            if(format.equals("gif"))
                Utils.saveGifIntoFileFromUri(getApplicationContext(), url, saveName);
            else
                Utils.saveImageIntoFileFromUri(getApplicationContext(), rotatedBitmap, hashName);

            //Glide 이용해 이미지 표기 
            Glide.with(context)
                    .load(url)
                    .into(thumbnail);

            cursor.close();

        } catch (FileNotFoundException e) {
            saveName = null;
            e.printStackTrace();
        } catch (IOException e) {
            saveName = null;
            e.printStackTrace();
        }

    }
}

Manifest에 Glide 선언

//build.gradle(Module:your app name.app)
//선언후 sync 필수!
dependencies {
    implementation 'com.github.bumptech.glide:glide:4.4.0'
}

내부저장소에 gif 이미지 파일 복사하기
duplicate gif file to internal starage

//gif 원본파일 복사해 저장하기
    public static final void saveGifIntoFileFromUri(Context context, Uri uri, String fileName) {
        InputStream openInputStream = null;

        File file = new File(getFilePath(context), fileName);
        try {
            openInputStream = context.getContentResolver().openInputStream(uri);
            if (openInputStream != null) {
                InputStream inputStream = openInputStream;
                InputStream inputStream2 = inputStream;
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                long copyTo$default = copyTo$default(inputStream2, fileOutputStream, 0, 2, null);
                fileOutputStream.close();
                Long.valueOf(copyTo$default);
                inputStream.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.e("Utils","saveGifIntoFileFromUri FileNotFoundException : "+ e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("Utils","saveGifIntoFileFromUri IOException : "+ e.toString());
        }
 }

내부저장소에 이미지 파일 복사해 저장하기
duplicate rotated image file to internal storage

//회전된 이미지 파일 내부 저장소에 저장하기
public static void saveImageIntoFileFromUri(Context context, Bitmap bitmap, String fileName) {
    File file = new File(getFilePath(context), fileName);
    try {
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        switch(file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(".") + 1)){
            case "jpeg":
            case "jpg":
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
                break;
            case "png":
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                break;
        }

        bitmap.recycle();
        fileOutputStream.close();

	} catch (FileNotFoundException e) {
        e.printStackTrace();
        Log.e("Utils","saveImageIntoFileFromUri FileNotFoundException : "+ e.toString());
    } catch (IOException e) {
        e.printStackTrace();
        Log.e("Utils","saveImageIntoFileFromUri IOException : "+ e.toString());
    }
}

앱 내부 저장소 경로 가지고 오기
get app internal storage path

//앱 내부 저장소 경로 가지고 오기
public static String getFilePath(Context context) {
    String filePath = context.getFilesDir().getPath();
    Log.e("Utils","getFilesDir " +  context.getFilesDir().getPath());
    return filePath;
}

새로운 bitmap 파일에 원본 이미지 회전 정보 반영하기
Reflect original image rotation information in new bitmap file

//원본 이미지의 회전 상태를 새로운 bitmap에 반영
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
    ExifInterface ei = new ExifInterface(image_absolute_path);
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            return rotate(bitmap, 90);

        case ExifInterface.ORIENTATION_ROTATE_180:
            return rotate(bitmap, 180);

        case ExifInterface.ORIENTATION_ROTATE_270:
            return rotate(bitmap, 270);

        case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
            return flip(bitmap, true, false);

        case ExifInterface.ORIENTATION_FLIP_VERTICAL:
            return flip(bitmap, false, true);

        default:
            return bitmap;
    }
}

//이미지 회전
public static Bitmap rotate(Bitmap bitmap, float degrees) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degrees);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

//이미지 뒤집기
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
    Matrix matrix = new Matrix();
    matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

참고 : 이미지 파일의 용량, 가로, 세로 크기 구하기
ps : get image file size, width, height

 //bitmap file size, width, height 구하기 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(duplicateFile.getAbsolutePath(),options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; Log.e(getClass().getSimpleName(), "duplicateFile size :" + dump.length()); Log.e(getClass().getSimpleName(), "duplicateFile width * height : " + imageWidth + " * " + imageHeight);



728x90
반응형

댓글