android exifinterface - 요약 : Camera Intent를 사용하여 사진을 찍고 올바른 방향으로 사진을 표시합니다 (모든 장치에서 잘 작동 함).





bitmap tag_orientation (5)


업데이트 : 2014 년 1 월 2 일 : 기기 제조업체를 기반으로 다양한 전략을 구현하는 것을 피하기 위해 노력했습니다. 불행히도, 나는 주변을 둘러 보지 못했습니다. 수백 개의 게시물을 읽고 여러 개발자와 이야기를 나누면서 아무도 장치 제조업체의 특정 코드를 구현하지 않고 모든 장치에서 작동하는 솔루션을 찾지 못했습니다.

StackOverflow에서 내 솔루션을 게시 한 후 일부 개발자는 github에 내 코드를 게시하도록 요청했습니다. 이제 여기에 있습니다 : AndroidCameraUtil on github

이 코드는 Android API-Level> = 8 인 다양한 기기에서 성공적으로 테스트되었습니다. 전체 목록은 github에있는 Readme 파일을 참조하십시오.

CameraIntentHelperActivity 는 주요 기능을 제공하며, 다음에서 더 자세히 설명됩니다.

기본 카메라 작업 호출 :

  • 삼성 및 소니 기기 : startActivityForResult 메소드 호출로 카메라 활동을 호출합니다. CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE 상수 만 설정합니다. 나는 다른 의도 사항을 설정하지 않습니다.
  • 다른 모든 장치의 경우 : 이전처럼 startActivityForResult 메서드 호출로 카메라 작업을 호출합니다. 그러나 이번에는 추가로 MediaStore.EXTRA_OUTPUT을 추가로 설정하고 이미지를 저장하려는 URI를 제공합니다.

두 경우 모두 카메라 작동이 시작된 시간을 기억합니다.

카메라 활동 결과 :

  1. Mediastore : 먼저 MediaStore에서 캡처 한 사진을 읽으려고합니다. MediaStore 콘텐츠에 mangedQuery를 사용하여 찍은 최신 이미지와 오리엔테이션 속성 및 타임 스탬프를 검색합니다. 이미지를 찾으면 카메라 의도가 호출되기 전에 촬영되지 않았습니다. 이는 내가 찾고있는 이미지입니다. 그렇지 않으면 결과를 무시하고 다음 접근 방식 중 하나를 시도합니다.
  2. Intent extra : 두 번째로, intent.getData ()에서 Uri 이미지를 가져 오려고합니다. 이 방법도 성공하지 못하면 3 단계로 진행합니다.
  3. 기본 사진 Uri : 위에서 언급 한 모든 단계가 작동하지 않으면 카메라 활동으로 넘어간 이미지 Uri를 사용합니다.

이 시점에서, 나는 UploadPhotoActivity에 전달하는 사진 Uri와 방향을 검색했습니다.

이미지 처리

BitmapHelper 클래스를 자세히 살펴보십시오. 튜토리얼 에 자세히 설명 된 코드를 기반으로합니다.

또한 shrinkBitmap 메서드는 이전에 추출한 방향 정보를 기반으로 필요한 경우 이미지를 회전합니다.

나는 이것이 당신 중 일부에게 도움이되기를 바랍니다.

그것은 세계에서 가장 간단한 것 같습니다 : 기본 카메라 활동을 사용하여 안드로이드 애플 리케이션 내에서 사진을 찍어. 그러나 및 웹에서 여러 게시물에 포함 된 함정이 많이 있습니다. 예를 들어 Null Intents가 전달되고 그림의 방향이 정확하지 않거나 OutOfMemoryErrors입니다.

내가 할 수있는 해결책을 찾고있다.

  1. 카메라 의도를 통해 카메라 활동을 시작하고,
  2. 사진의 Uri 검색
  3. 사진의 올바른 방향을 검색하십시오.

또한, 나는 가능한 한 멀리 장치 구성 (제조 업체, 모델, OS 버전) 특정 구현을 피하기 위해 싶습니다. 그래서 나는 궁금해 : 이것을 달성하는 가장 좋은 방법은 무엇입니까?




Sony Xperia Go, 삼성 Galaxy SII, Samsung Galaxy SIII mini 및 모든 장치에서 작동하는 Samsung Galaxy Y로이 코드를 테스트했습니다!

그러나 LG E400 (2.3.6)에서는 작동하지 않았고 갤러리에서 두 장의 사진을 얻습니다. 그래서 void startCameraIntent ()에 manufacturer.contains ( "lge")를 추가하고 문제를 수정했습니다.

if(!(manufacturer.contains("samsung")) && !(manufacturer.contains("sony")) && !(manufacturer.contains("lge"))) {
    String filename = System.currentTimeMillis() + ".jpg";
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, filename);
    cameraPicUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraPicUri);
}



CM 10.1 Galaxy S3에서 BitmapHelper에서 nullpointer 예외가 발생했습니다.

bm = BitmapFactory.decodeFileDescriptor (fileDescriptor.getFileDescriptor (), null, options);

이후 UploadPhotoActivity가 다음에서 실패합니다.

    try {
        photo = BitmapHelper.readBitmap(this, cameraPicUri);
        if (photo != null) {
            photo = BitmapHelper.shrinkBitmap(photo, 600, rotateXDegrees);
            thumbnail = BitmapHelper.shrinkBitmap(photo, 100);
            ImageView imageView = (ImageView) findViewById(R.id.sustainable_action_photo);
            imageView.setImageBitmap(photo);                
        } else {
            Log.e(TAG,"IMAGE ERROR 1");
        }
    } catch (Exception e) {
            Log.e(TAG,"IMAGE ERROR 2");
        e.printStackTrace();
    }

두 번째 로그 (IMAGE ERROR 2). 몇 번 시도한 후 카메라가 고장 났는데 "카메라에 연결할 수 없습니다"라는 오류가 발생했습니다.

넥서스 7에서 테스트하여 완벽하게 작동합니다.

편집 : 이것을 다음과 같이 좁혔습니다.

fileDescriptor = context.getContentResolver (). openAssetFileDescriptor (selectedImage, "r");

selectedImage에는 다음이 포함됩니다.

file : ///storage/emulated/0/DCIM/Camera/IMG_20131023_183343.jpg

fileDescriptor는 FileNotFoundException를 리턴합니다. 파일 시스템을 검사했는데 이미지가이 위치에 저장되지 않았습니다. TakePhotoActivity의 cameraPicUri가 존재하지 않는 이미지를 가리 킵니다. 나는 현재 그것이 모두 잘못되었는지 확인하고있다.

Edit2 : 나는 오류를 알아 냈어 : 장치가 삼성이고, 그것이 삼성 장치임을 응용 프로그램에 알리기 때문에, 당신의 삼성 특정 수정 프로그램이 적용됩니다. Cyanogenmod는 이러한 수정이 필요 없으며 결국 코드가 손상됩니다. 일단 제거하면

(manufacturer.contains ( "samsung")) &&

그것은 작동합니다. 이것은 맞춤 ROM이므로 당연히이를 계획 할 수는 없습니다. 장치가 cyanogenmod를 실행 중인지를 감지하고이를 코드에 포함시키는 방법을 찾아 내기 위해 노력하고 있습니다.

좋은 카메라 수정을 가져 주셔서 감사합니다!

Edit3 : 코드를 다음과 같이 변경하여 Galaxy S3의 Cyanogenmod에서 실행되도록 수정했습니다. 이제는 가끔은 효과가 있지만 가끔은 그렇지 않습니다. 이상한.

if (manufacturer.contains ( "sony")) &&! (manufacturer.contains ( "samsung")) lge ")))))




Sony Xperia Z5에서이 기능을 사용할 때 몇 가지 문제가 발생합니다.

나는 이것을 추가했고 훨씬 나아졌다.

if (buildType.contains("sony")&& buildDevice.contains("e5823")) {
                setPreDefinedCameraUri = true;}

그러나 22 번 중 4 번은 카메라를 다시 시작한 후 2 번 다시 시작했습니다. 모든 테스트로 인해 앱이 다시 시작되었습니다. 이 문제를 해결할 수있는 방법이 있습니까? 아니면이 결과를 받아 들일 수 있습니까?

문제는 카메라가 다시 시작되면 뒤로 버튼을 두 번 누르고 붐을 일으킬 수 있다는 것입니다. 이미지가 내 Imageview에 저장되어 저장됩니다.




사용 된 gradle 이 즉시 실행에 문제가있을 gradle 문제가 발생합니다.
그래서이 문제를 해결하려면 gradle 버전을 변경하거나 즉석 실행을 비활성화해야합니다.





android android-intent camera orientation