Tech & Programming/모바일(Android, Flutter)

View의 내용을 어떻게 이미지 파일로 만들었나요?

소스코드 요리사 2019. 5. 7. 20:37

2018/12/30 - [Toy Project] - 2019년 신년 메시지는 '기분 좋은 인사' 로 보내세요.

 

2019년 신년 메시지는 '기분 좋은 인사' 로 보내세요.

'기분 좋은 인사 : 2019년, 새해 인사말 및 안부, 감사, 경조사 등 인사말' 확인 - https://play.google.com/store/apps/details?id=com.toyproject.greeting 2019년 새해, 지인들에게 '기분 좋은 인사'로 새해인..

developside.tistory.com

  지난 번 면접시에 사이드프로젝트로 진행한 '기분 좋은 인사' 의 기능을 설명하면서, 이미지와 사용자가 입력한 메시지 텍스트를 어떻게 이미지 파일로 만들어 보내냐는 질문을 받았었습니다. 코드를 작성한 지 오래되서 알음알음 대답을 했었습니다. 그래서, 이 참에 다시 정리나 해놓자 싶어 블로깅합니다.

 

먼저, '기분 좋은 인사' 제가 설명한 기능이 어떤 동작을 하는지 알아야 될 것 같아 조금 상세히 설명드리겠습니다.

'기분 좋은 인사' 어플리케이션에서 보낼 이미지를 선택하고, 이미지와 함께 보낼 메시지를 입력하면, 왼쪽 이미지와 같이 글자 크기, 글자/배경색 등을 변경할 수 있습니다. 

그리고, 카카오톡 또는 문자 보내기 등 공유를 하면 이미지와 보낼 메시지를 이미지파일(png)로 만들어 공유를 하게 됩니다.

 

동작 원리는 1. 먼저 Bitmap.createBitmap() 함수를 통해 Bitmap을 생성합니다.

그리고, 2.생성된 Bitmap으로 Canvas를 생성합니다. 이미지뷰와 텍스트뷰의 내용(정확히 말하면 이미지뷰와 텍스트뷰의 Parent 뷰)을 Canvas를 통해 create 된 bitmap에 그립니다.  

마지막으로, 3. Bitmap을 png 파일로 쓰면 됩니다.

 

 

 

동작원리가 구현된 소스코드 발췌하여 공유합니다.

아래는 소스코드는 View를 그린 Bitmap을 리턴받는 메소드입니다.

Bitmap.createBitmap 에 대해서는 https://developer.android.com/reference/android/graphics/Bitmap 을 참조하시면 됩니다.

private Bitmap getBitmapFromView(View v) {
        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.draw(c);
        return b;
    }

 

그리고, 아래 코드는 그 Bitmap을 png 파일로 만드는 메소드입니다.

파일로 지정된 경로에 쓰고, 그 URI를 카카오톡이나 SMS 프로그램에 Intent로 넘기도록 되어 있습니다.

    public Uri saveBitmapAndGetURI(Bitmap bitmap, String folder){
            final String IMG_FILE_EXTENSION = ".png";
            new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            String ex_storage = Environment.getExternalStorageDirectory().getAbsolutePath();
            String file_name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + IMG_FILE_EXTENSION;
            String fullFileName = ex_storage + folder;
            File file_path;
            try{
                file_path = new File(fullFileName);
                if(!file_path.isDirectory()){
                    file_path.mkdirs();
                }
                file = new File(file_path, file_name);
                FileOutputStream out = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.PNG, 80, out);
                out.close();

                Uri providerURI;
                if(Build.VERSION.SDK_INT < 24) {
                    providerURI = Uri.fromFile(file);
                }
                else {
                    providerURI = FileProvider.getUriForFile(getBaseContext(), getPackageName(), file);
                }

                return providerURI;
            }
            catch(FileNotFoundException exception) {
                Log.e(TAG,"FileNotFoundException : " + exception.getMessage());
            }
            catch(IOException exception) {
                Log.e(TAG,"IOException : " + exception.getMessage());
            }
            return null;
        }

 

View를 이미지 파일로 저장해야하는 필요가 있으신 분에게 위 소스 및 설명이 개발에 도움이 되셨으면 좋겠습니다.