그냥 간단하게 사진 자르기 해서 이미지 넣으려고 했는데


킷캣에서 부터 팅기는 현상이 발생했다.



팅기는 영상.



정말 뜬금없다. 킷캣 전부터는 쭉 잘 되던거였는데... 


웃긴 건 이상하게 특정사진만 자르면 팅긴다. 원본사진은 100kb밖에 안되는 사진인데도 말이다.


도대체 원인 뭔지 한참을 찾아헤맸다.


어찌어찌 해결을 됐는데 완벽한 해결책은 아니다..


킷캣문제인가 해서 찾아보기도 하고..


참고한 링크들이다.


http://blog.tstore.co.kr/107


https://plus.google.com/112692779577336772166/posts/9MbmSsUcd1e


http://www.androidside.com/plugin/mobile/board.php?bo_table=B49&wr_id=81704


안드로이드 사이드 위 글을 보고 해결을 했다.


사진 크롭 코드를 보면 이런 부분이 있다.

기존 코드는 이렇게 되어있었는데


intent.putExtra("outputX", 120);

intent.putExtra("outputY", 130);


안드로이드사이드 글에서 이게 문제라는 댓글을 보았다.



그래서 저 숫자를 

intent.putExtra("outputX", 100);

intent.putExtra("outputY", 100);


100로 작게 바꿔주었다.


그랬더니?? 신기하게 팅기지가 않는다. 최소한 내 폰에서는...



그래서 임시방편으로나마 해결을 했는데 찜찜하다.

다른 폰에서는 자르기는 되는데 자른 이미지가 깨진건지 안나온다;;;



찾아보면서 얻은 결론은


 메모리 부족으로 발생하는 것이다.

 바인더 Intent에 1MB 이상의 데이터를 넘기게되면 발생할 수 있다.

보통 제공되는 크롭을 사용하게 되면 발생하므로 이미지 크롭의 경우 직접 구현해서 사용하는게 낫다는 의견

하지만 직접 구현할 능력이..;; 그리고 찾아본 예제들은 거의 다 기본 제공 크롭소스이다..



마지막으로 위 영상의 예제 코드를 올린다.

아마도 다 이 코드를 쓸 것이다. 퍼질대로 퍼진 대중적인 코드(xml은 제외)



package com.example.camera

import java.io.File;
import com.example.camera.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity implements OnClickListener {
	private ImageView mPhotoImageView;// 이미지 받기
	private ImageView foot;
	private Uri mImageCaptureUri;

	private static final int PICK_FROM_CAMERA = 0;
	private static final int PICK_FROM_ALBUM = 1;
	private static final int CROP_FROM_CAMERA = 2;
	LinearLayout bar, mother = null;
	FrameLayout container = null;
	Bitmap bm = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Button mButton = (Button) findViewById(R.id.load);
		mPhotoImageView = (ImageView) findViewById(R.id.profile);
		mButton.setOnClickListener(this);
	}

	private void doTakePhotoAction() {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

		// 임시로 사용할 파일의 경로를 생성
		String url = "tmp.jpg";

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

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

		// 특정기기에서 사진을 저장못하는 문제가 있어 다음을 주석처리 합니다.
		// intent.putExtra("return-data", true);
		startActivityForResult(intent, PICK_FROM_CAMERA);

	}

	private void doTakeAlbumAction() {
		// 앨범 호출
		Intent intent = new Intent(Intent.ACTION_PICK);
		intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE);
		startActivityForResult(intent, PICK_FROM_ALBUM);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != RESULT_OK) {
			return;
		}

		switch (requestCode) {
		case CROP_FROM_CAMERA: {
			// 크롭이 된 이후의 이미지를 넘겨 받습니다.
			// 이미지뷰에 이미지를 보여준다거나 부가적인 작업 이후에
			// 임시 파일을 삭제합니다.
			final Bundle extras = data.getExtras();

			if (extras != null) {
				Bitmap photo = extras.getParcelable("data");
				mPhotoImageView.setImageBitmap(photo);
			}

			// 임시 파일 삭제
			File f = new File(mImageCaptureUri.getPath());
			if (f.exists()) {
				f.delete();
			}

			break;
		}

		case PICK_FROM_ALBUM: {
			// 이후의 처리가 카메라와 같으므로 일단 break없이 진행합니다.
			// 실제 코드에서는 좀더 합리적인 방법을 선택하시기 바랍니다.

			mImageCaptureUri = data.getData();
		}

		case PICK_FROM_CAMERA: {
			// 이미지를 가져온 이후의 리사이즈할 이미지 크기를 결정합니다.
			// 이후에 이미지 크롭 어플리케이션을 호출하게 됩니다.

			Intent intent = new Intent("com.android.camera.action.CROP");
			intent.setDataAndType(mImageCaptureUri, "image/*");

			intent.putExtra("outputX", 120);
			intent.putExtra("outputY", 130);
			// intent.putExtra("aspectX", 1);
			// intent.putExtra("aspectY", 1);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);

			startActivityForResult(intent, CROP_FROM_CAMERA);

			break;
		}
		}
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.load) {
			DialogInterface.OnClickListener cameraListener = new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					doTakePhotoAction();
				}
			};

			DialogInterface.OnClickListener albumListener = new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					doTakeAlbumAction();
				}
			};

			DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
			};

			new AlertDialog.Builder(this).setTitle("업로드할 이미지 선택")
					.setPositiveButton("사진촬영", cameraListener)
					.setNeutralButton("앨범선택", albumListener)
					.setNegativeButton("취소", cancelListener).show();

		}

	}
}




팅길 때 찍힌 로그.



12-14 20:59:51.831: E/JavaBinder(1242): !!! FAILED BINDER TRANSACTION !!!

12-14 20:59:51.831: I/ActivityManager(1242): Restarting because process died: ActivityRecord{42d64570 u0 com.example.camera/.MainActivity t1511}

12-14 20:59:51.831: D/AlwaysOnTopManagerService(1242): setRearTouchLongPress(): flag = false, mIsLongPress = false

12-14 20:59:51.851: W/WindowManager(1242): view not successfully added to wm, removing view

12-14 20:59:51.861: E/JavaBinder(1242): !!! FAILED BINDER TRANSACTION !!!

12-14 20:59:51.861: W/ActivityManager(1242): Exception when starting activity com.example.camera/.MainActivity

12-14 20:59:51.861: W/ActivityManager(1242): android.os.TransactionTooLargeException

12-14 20:59:51.861: W/ActivityManager(1242): at android.os.BinderProxy.transact(Native Method)

12-14 20:59:51.861: W/ActivityManager(1242): at android.app.ApplicationThreadProxy.scheduleLaunchActivity(ApplicationThreadNative.java:761)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1072)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1168)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStack.resumeTopActivityLockedInner(ActivityStack.java:2327)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1482)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStackSupervisor.resumeTopActivitiesLocked(ActivityStackSupervisor.java:2196)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1077)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:964)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:5364)

12-14 20:59:51.861: W/ActivityManager(1242): at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:427)

12-14 20:59:51.861: W/ActivityManager(1242): at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2159)

12-14 20:59:51.861: W/ActivityManager(1242): at android.os.Binder.execTransact(Binder.java:404)

12-14 20:59:51.861: W/ActivityManager(1242): at dalvik.system.NativeStart.run(Native Method)

12-14 20:59:51.872: D/WindowManager(1242): win:Window{435b3a88 u0 com.example.camera/com.example.camera.MainActivity}mOemFlagWin:null,mSaveOemFlags:0,mCurrentFocus:Window{449c9898 u0 com.android.gallery3d/com.android.gallery3d.filtershow.crop.CropActivity}

12-14 20:59:51.882: I/ActivityManager(1242): Start proc com.example.camera for activity com.example.camera/.MainActivity: pid=6109 uid=10007 gids={50007}

12-14 20:59:51.882: D/ActivityManager(1242): checkHideDockBarApplication.result = NOK

12-14 20:59:51.892: D/dalvikvm(6109): Late-enabling CheckJNI

12-14 20:59:51.922: D/dalvikvm(6109): Debugger has detached; object registry had 1 entries

12-14 20:59:51.922: E/JavaBinder(1242): !!! FAILED BINDER TRANSACTION !!! 


위 로그를 보고 어느 분이 달아주신 댓글..


TransactionTooLargeException 발생한거네요..
바인더 Intent에 1MB 이상의 데이터를 넘기게되면 발생할 수 있습니다.
보통 제공되는 크롭을 사용하게 되면 발생하구요.. 이미지 크롭의 경우 직접 구현해서 사용하는게 낫습니다.


나중에 좀 더 완벽한 해결책을 적용할 수 있으면 좋겠다.




+ Recent posts