차근차근/Android

안드로이드/Android 사진, 갤러리 Image Crop 후 MMS 전송 하기

예쁜꽃이피었으면 2014. 8. 28. 17:54

http://arabiannight.tistory.com/45




▒ ▒  ▒  ▒  ▒  ▒  ▒  전체 소스 입니다.  ▒ ▒  ▒  ▒  ▒  ▒  ▒  
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
public class TestImageCropActivity extends Activity {
 
    private static final String TAG = "TestImageCropActivity";
 
    private static final int PICK_FROM_CAMERA = 0;
    private static final int PICK_FROM_ALBUM = 1;
    private static final int CROP_FROM_CAMERA = 2;
 
    private Uri mImageCaptureUri;
    private AlertDialog mDialog;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        setLayout();
         
    }
 
    /**
     Button Click
     */
    public void onButtonClick(View v){
        switch (v.getId()) {
        case R.id.btn_sns:
            sendSMS("01000000000" , "hi nice to meet you");
            break;
        case R.id.btn_mms:
            Log.e(TAG, "mImageCaptureUri = " + mImageCaptureUri);
            sendMMS(mImageCaptureUri);
//          sendMMSG();
            break;
        case R.id.btn_image_crop:
            mDialog = createDialog();
            mDialog.show();
            break;
        }
    }
 
    /**
     * 다이얼로그 생성
     */
    private AlertDialog createDialog() {
        final View innerView = getLayoutInflater().inflate(R.layout.image_crop_row, null);
 
        Button camera = (Button)innerView.findViewById(R.id.btn_camera_crop);
        Button gellary = (Button)innerView.findViewById(R.id.btn_gellary_crop);
 
        camera.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                doTakePhotoAction();
                setDismiss(mDialog);
            }
        });
 
        gellary.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                doTakeAlbumAction();
                setDismiss(mDialog);
            }
        });
 
        AlertDialog.Builder ab = new AlertDialog.Builder(this);
        ab.setTitle("이미지 Crop");
        ab.setView(innerView);
 
        return  ab.create();
    }
 
    /**
     * 다이얼로그 종료
     */
    private void setDismiss(AlertDialog dialog){
        if(dialog!=null&&dialog.isShowing()){
            dialog.dismiss();
        }
    }
 
    /**
     * SMS 발송   
     */
    private void sendSMS(String reciver , String content){
        Uri uri = Uri.parse("smsto:"+reciver);  
        Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
        it.putExtra("sms_body", content);  
        startActivity(it); 
    }
     
    /**
     * MMS 발송   (APP TAB BOX)
     */
    private void sendMMS(Uri uri){
        uri = Uri.parse(""+uri);  
        Intent it = new Intent(Intent.ACTION_SEND);  
        it.putExtra("sms_body", "some text");  
        it.putExtra(Intent.EXTRA_STREAM, uri);  
        it.setType("image/*");
        // 삼성 단말에서만 허용 ( 앱 선택 박스 없이 호출 )
//      it.setComponent(new ComponentName("com.sec.mms", "com.sec.mms.Mms"));
        startActivity(it);
    }
     
    /**
     * MMS 발송 ( 첨부 파일 없음 )
     */
    private void sendMMSG(){
        Uri mmsUri = Uri.parse("mmsto:");
        Intent sendIntent = new Intent(Intent.ACTION_VIEW, mmsUri); 
        sendIntent.addCategory("android.intent.category.DEFAULT");
        sendIntent.addCategory("android.intent.category.BROWSABLE");
        sendIntent.putExtra("address", "01000000000");
        sendIntent.putExtra("exit_on_sent", true);
        sendIntent.putExtra("subject", "dfdfdf");
        sendIntent.putExtra("sms_body", "dfdfsdf");
        Uri dataUri = Uri.parse(""+mImageCaptureUri);
        sendIntent.putExtra(Intent.EXTRA_STREAM, dataUri);
 
        startActivity(sendIntent);
    }
     
 
    /**
     * 카메라 호출 하기
     */
    private void doTakePhotoAction()
    {
        Log.i(TAG, "doTakePhotoAction()");
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Crop된 이미지를 저장할 파일의 경로를 생성
        mImageCaptureUri = createSaveCropFile();
        intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
        startActivityForResult(intent, PICK_FROM_CAMERA);
    }
 
    /**
     * 앨범 호출 하기
     */
    private void doTakeAlbumAction()
    {
        Log.i(TAG, "doTakeAlbumAction()");
        // 앨범 호출
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE);
        startActivityForResult(intent, PICK_FROM_ALBUM);
    }
 
    /**
     * Result Code
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        Log.d(TAG, "onActivityResult");
        if(resultCode != RESULT_OK)
        {
            return;
        }
 
        switch(requestCode)
        {
        case PICK_FROM_ALBUM:
        {
            Log.d(TAG, "PICK_FROM_ALBUM");
             
            // 이후의 처리가 카메라와 같으므로 일단  break없이 진행합니다.
            // 실제 코드에서는 좀더 합리적인 방법을 선택하시기 바랍니다.
            mImageCaptureUri = data.getData();
            File original_file = getImageFile(mImageCaptureUri);
             
            mImageCaptureUri = createSaveCropFile();
            File cpoy_file = new File(mImageCaptureUri.getPath());
 
            // SD카드에 저장된 파일을 이미지 Crop을 위해 복사한다.
            copyFile(original_file , cpoy_file);
        }
 
        case PICK_FROM_CAMERA:
        {
            Log.d(TAG, "PICK_FROM_CAMERA");
 
            // 이미지를 가져온 이후의 리사이즈할 이미지 크기를 결정합니다.
            // 이후에 이미지 크롭 어플리케이션을 호출하게 됩니다.
 
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setDataAndType(mImageCaptureUri, "image/*");
             
            // Crop한 이미지를 저장할 Path
            intent.putExtra("output", mImageCaptureUri);
             
            // Return Data를 사용하면 번들 용량 제한으로 크기가 큰 이미지는
            // 넘겨 줄 수 없다.
//          intent.putExtra("return-data", true);
            startActivityForResult(intent, CROP_FROM_CAMERA);
 
            break;
        }
         
        case CROP_FROM_CAMERA:
        {
            Log.w(TAG, "CROP_FROM_CAMERA");
             
            // Crop 된 이미지를 넘겨 받습니다.
            Log.w(TAG, "mImageCaptureUri = " + mImageCaptureUri);
 
            String full_path = mImageCaptureUri.getPath();
            String photo_path = full_path.substring(4, full_path.length());
             
            Log.w(TAG, "비트맵 Image path = "+photo_path);
             
            Bitmap photo = BitmapFactory.decodeFile(photo_path);
            mPhotoImageView.setImageBitmap(photo);
 
            break;
        }
        }
    }
     
    /**
     * Crop된 이미지가 저장될 파일을 만든다.
     * @return Uri
     */
    private Uri createSaveCropFile(){
        Uri uri;
        String url = "tmp_" + String.valueOf(System.currentTimeMillis()) + ".jpg";
        uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), url));
        return uri;
    }
 
 
    /**
     * 선택된 uri의 사진 Path를 가져온다.
     * uri 가 null 경우 마지막에 저장된 사진을 가져온다.
     * @param uri
     * @return
     */
    private File getImageFile(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        if (uri == null) {
            uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        }
 
        Cursor mCursor = getContentResolver().query(uri, projection, null, null,
                MediaStore.Images.Media.DATE_MODIFIED + " desc");
        if(mCursor == null || mCursor.getCount() < 1) {
            return null; // no cursor or no record
        }
        int column_index = mCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        mCursor.moveToFirst();
 
        String path = mCursor.getString(column_index);
 
        if (mCursor !=null ) {
            mCursor.close();
            mCursor = null;
        }
 
        return new File(path);
    }
 
    /**
     * 파일 복사
     * @param srcFile : 복사할 File
     * @param destFile : 복사될 File
     * @return
     */
    public static boolean copyFile(File srcFile, File destFile) {
        boolean result = false;
        try {
            InputStream in = new FileInputStream(srcFile);
            try {
                result = copyToFile(in, destFile);
            } finally  {
                in.close();
            }
        } catch (IOException e) {
            result = false;
        }
        return result;
    }
 
    /**
     * Copy data from a source stream to destFile.
     * Return true if succeed, return false if failed.
     */
    private static boolean copyToFile(InputStream inputStream, File destFile) {
        try {
            OutputStream out = new FileOutputStream(destFile);
            try {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) >= 0) {
                    out.write(buffer, 0, bytesRead);
                }
            } finally {
                out.close();
            }
            return true;
        } catch (IOException e) {
            return false;
        }
    }
 
    /*
     * Layout
     */
    private ImageView mPhotoImageView;
 
    private void setLayout(){
        mPhotoImageView = (ImageView)findViewById(R.id.img_bitmap);
    }
}


▒ ▒  ▒  ▒  ▒  ▒  ▒  디테일 설명 입니다.  ▒ ▒  ▒  ▒  ▒  ▒  ▒  

▒ 1.  
참고사이트 : http://theeye.pe.kr/entry/example-of-image-crop-with-camera-and-album-picker-on-android 

아이군님의 블로그의 Crop소스 를 참고였습니다. 참 설명이 잘 되있어서 보기 편했는데요. 바뀐점이 있다면 Crop후 이미지를 넘기는 과정에서 번들은 사용해서 넘기셨기대문에 고화질의 사진을 Crop할 경우 Return Data를 넘기지 못하는 현상이 발생하였습니다. 그래서 Crop이 정상 작동 하지 않는 경우가 생기게 되어, 일단 File을 생성 후 그 파일을 Crop한 후 저장하는 형식으로 수정 하 였습니다. 전체적인 틀은 비슷하게 가고 나머지 부분은 약간씩 수정 되었구요. SMS와 Crop한 이미지를 전송하는 MMS 기능을 추가 하였습니다.


▒ 2. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
case PICK_FROM_CAMERA:
        {
            Log.d(TAG, "PICK_FROM_CAMERA");
 
            // 이미지를 가져온 이후의 리사이즈할 이미지 크기를 결정합니다.
            // 이후에 이미지 크롭 어플리케이션을 호출하게 됩니다.
 
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setDataAndType(mImageCaptureUri, "image/*");
             
            // Crop한 이미지를 저장할 Path
            intent.putExtra("output", mImageCaptureUri);
             
            // Return Data를 사용하면 번들 용량 제한으로 크기가 큰 이미지는
            // 넘겨 줄 수 없다.
//          intent.putExtra("return-data", true);
            startActivityForResult(intent, CROP_FROM_CAMERA);
 
            break;
        }

intent.putExtra("output", mImageCaptureUri);
아웃풋 경로 지정함으로써 Crop 된 이미지가 해당 Uri로 Ruturn 되도록 설정 하였습니다. 


▒ 3.   
1
2
3
4
5
6
7
8
9
10
/**
 * Crop된 이미지가 저장될 파일을 만든다.
 * @return Uri
 */
private Uri createSaveCropFile(){
    Uri uri;
    String url = "tmp_" + String.valueOf(System.currentTimeMillis()) + ".jpg";
    uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), url));
    return uri;
}

Crop이 완료된 파일은 해당 기기의 SDcard에 저장 됩니다.
 




▒ 4. 파일첨부 및 스크린샷.    

 TestImageCrop.zip





반응형