카메라나 갤러리로부터 이미지를 가져와서 Crop 하여 Crop된 이미지를 저장하는 코드이다. 

다음 주소들을 참고하였다. (사실 거의 배낀 수준.. 설명이 아주 잘 나와있다.)


http://theeye.pe.kr/entry/example-of-image-crop-with-camera-and-album-picker-on-android

http://blog.naver.com/PostView.nhn?blogId=legendx&logNo=40132435162


- 갤러리에서 이미지 가져오는 부분

private void getPhotoFromGallery() { // 갤러리에서 이미지 가져오기 

Intent intent = new Intent(Intent.ACTION_PICK);

intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE);

startActivityForResult(intent, PICK_FROM_GALLERY);

}



- 카메라 촬영 후 이미지 가져오는 부분

private void getPhotoFromCamera() { // 카메라 촬영 후 이미지 가져오기

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);


// 임시로 사용할 파일의 경로를 생성

String url = "tmp_" + String.valueOf(System.currentTimeMillis()) + ".jpg";

mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), url));

intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

startActivityForResult(intent, PICK_FROM_CAMERA);

}



- onActivityResult() 에서 requestCode 별로 동작하도록 함

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

 

if (resultCode != RESULT_OK)

return;

switch (requestCode) {

case PICK_FROM_GALLERY: 

{

mImageCaptureUri = data.getData();

Log.i("NR", mImageCaptureUri.getPath().toString());


// 이후의 처리가 카메라 부분과 같아 break 없이 진행

}

case PICK_FROM_CAMERA:

{

Intent intent = new Intent("com.android.camera.action.CROP");

intent.setDataAndType(mImageCaptureUri, "image/*");


// crop한 이미지를 저장할때 200x200 크기로 저장

intent.putExtra("outputX", 200); // crop한 이미지의 x축 크기

intent.putExtra("outputY", 200); // crop한 이미지의 y축 크기

intent.putExtra("aspectX", 2); // crop 박스의 x축 비율 

intent.putExtra("aspectY", 1); // crop 박스의 y축 비율

            intent.putExtra("scale", true);

intent.putExtra("return-data", true);

            startActivityForResult(intent, CROP_FROM_CAMERA);


break;

}

case CROP_FROM_CAMERA: 

{

final Bundle extras = data.getExtras();

// crop된 이미지를 저장하기 위한 파일 경로

String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp/" + System.currentTimeMillis() + ".jpg";


if (extras != null) {

Bitmap photo = extras.getParcelable("data"); // crop된 bitmap 

storeCropImage(photo, filePath);

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); // 갤러리를 갱신하기 위해..


...

}


File file = new File(mImageCaptureUri.getPath());

if (file.exists()) {

file.delete();

}

}

}



- Bitmap을 SD 카드에 저장하는 부분

private void storeCropImage(Bitmap bitmap, String filePath) {

File copyFile = new File(filePath);

BufferedOutputStream out = null;


try {

copyFile.createNewFile();

out = new BufferedOutputStream(new FileOutputStream(copyFile));

bitmap.compress(CompressFormat.JPEG, 100, out);

out.flush();

out.close();

} catch (Exception e) {         

e.printStackTrace();

}

}



Posted by 애이불비
l

화면마다 동일한 타이틀바가 필요하여 구글링하여 커스텀 타이틀바를 만들어 보았다. 허접하다..


1. 타이틀바 layout 만들기 


<custom_title.xml>


<?xml version="1.0" encoding="UTF-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@android:color/background_dark>

    <Button android:id="@+id/backBtn" 

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_centerVertical="true"

        android:layout_marginLeft="5dp"

        android:text="@string/btn_back" />

    

    <TextView android:id="@+id/titleTextView"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"

        android:textSize="18sp" />

    

    <Button android:id="@+id/nextBtn" 

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentRight="true"

        android:layout_centerVertical="true"

        android:layout_marginRight="5dp"

        android:text="@string/btn_next" />

    

</RelativeLayout>



2. values폴더의 styles.xml 에 테마 관련 정보 추가하기


<style name="CustomTitle" parent="android:Theme">

<item name="android:windowTitleSize">48dp</item>    

<item name="android:windowTitleBackgroundStyle">@style/CustomWindowTitleBackground</item>

</style>

    

<style name="CustomWindowTitleBackground">

<item name="android:background">#00000000</item>

</style>



3. AndroidManifest.xml 에 테마 설정하기 


<activity 

android:name=".Activity"

android:theme="@style/CustomTitle" />



4.  Activity.java에 다음 코드 넣기 


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

setContentView(R.layout.main);

getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);


...

}



끝.



Posted by 애이불비
l

액티비티 위에 새로운 액티비티가 뜨면서  

getResource().getDrawable(id) 부분에서 Out of Memory 오류가 발생하였다 오 갓뎀.....

결국 Manifest.xml 에서 Application 부분에 android:largeHeap="true" 옵션을 추가하였다.


뭔가 찝찝하여 largeHeap 옵션 없이 오류를 안 나게 하기 위해...  

기존 액티비티의 onPause() 에 DrawableUtil.recursiveRecycle(View root) (=> 구글에서 찾으면 쉽게 소스를 찾을 수 있다) 를 추가하였고, 새로운 액티비티의 onPause() 에도 넣었다. (onDestroy() 함수에  recycle 함수가 추가되어 있긴 했는데 onDestroy()가 호출되기 전에 다른 액티비티가 생성되어서 문제가 났다. 일일히 로그를 찍어보면서 확인..)

오류 없이 되긴 했는데.. 함수 호출 순서가 뒤엉켜서 애매했다. 


결국 largeHeap 추가로 끝.


http://aroundck.tistory.com/378 

여기를 보면 largeHeap 옵션은 HoneyComb (3.0) 부터 쓸 수 있고, 다른 App들을 죽일 수 있다고 한다.


Posted by 애이불비
l