android - ACTION_IMAGE_CAPTURE के साथ ली गई छवियां हमेशा कुछ नए उपकरणों पर ExifInterface.TAG_ORIENTATION के लिए 1 लौटाती हैं




image-capture (4)

ACTION_IMAGE_CAPTURE गतिविधि के साथ काम करते समय मुझे अभिविन्यास समस्या थी। मैंने TAG_ORIENTATION उपयोग किया है ताकि मैं तदनुसार तस्वीर घुमाए। लेकिन अब हमने पाया कि कुछ नए उपकरणों पर यह काम नहीं करता है। वास्तव में यह सभी उन्मुखताओं के लिए 1 लौटाता है।

यहां उन उपकरणों की सूची दी गई है जिन्हें हमने देखा है;

  • सैमसंग इन्फ्यूज 4 जी (2.3.3)
  • सैमसंग गैलेक्सी एसआईआई एक्स (2.3.5)
  • सोनी एक्सपीरिया आर्क (2.3.3)

दिलचस्प बात यह है कि एक बार यह छवि गैलरी है, यह ठीक से दिखाई देती है और यदि मैं इसे चुनता हूं, तो TAG_ORIENTATION ठीक से आबादी में TAG_ORIENTATION है। तो किसी भी तरह OS इस जानकारी को ठीक से भरता है लेकिन ActivityResult पर नहीं।

अभिविन्यास को समझने का सबसे विश्वसनीय तरीका क्या है? किसी अन्य प्रश्न पर किसी ने ऊंचाई और चौड़ाई की तुलना करने का सुझाव दिया लेकिन इन्हें प्राप्त करते समय, वे अभिविन्यास (एक और रहस्य) के आधार पर ठीक से स्विच किए जाते हैं।

संपादित करें: ऐसा लगता है कि यह किसी अन्य बग से कनेक्ट किया जा सकता है जहां ओएस गैलरी में ली गई छवि को डुप्लिकेट करता है (यह केवल हमारे द्वारा निर्दिष्ट यूआरएल में छवि को सहेजना है), बात यह है कि गैलरी में यह छवि ORIENTATION जानकारी है जबकि निर्दिष्ट स्थान में से एक नहीं है।

यह बग है; http://code.google.com/p/android/issues/detail?id=19268

EDIT-2: मैंने एंड्रॉइड के साथ एक नया बग दायर किया है। मुझे पूरा यकीन है कि यह एक ओएस बग उपर्युक्त बग से संबंधित है। http://code.google.com/p/android/issues/detail?id=22822


आप इस तरह से भी जा सकते हैं:

Matrix matrix = new Matrix();
// rotate the Bitmap (there a problem with exif so we'll query the mediaStore for orientation
Cursor cursor = getApplicationContext().getContentResolver().query(selectedImage,
      new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() == 1) {
cursor.moveToFirst();
    int orientation =  cursor.getInt(0);
    matrix.preRotate(orientation);
    }

इसके लिए मेरा समाधान। एलजी जी 2 मोबाइल पर परीक्षण किया गया। मैंने देखा कि जब मैं कैमरा का उपयोग करता हूं और नई तस्वीर लेता हूं तो सब ठीक काम करता है। ExifInterface सही अभिविन्यास देता है। तो यह पथ में कुछ होना चाहिए क्योंकि कोड की इस पंक्ति में मेरा पथ शून्य था:

exif = new ExifInterface(path);

लेकिन जब मैंने अपने ऐप क्रैश को पूर्ण पथ का उपयोग किया। लेकिन समाधान नीचे इस विधि में है, क्योंकि यह आपके एसडीके संस्करण पर निर्भर करता है। उल्लेख करने के लिए एक और नोट मैंने गैलरी चित्र का चयन करने के लिए केवल पूर्ण पथ का उपयोग किया क्योंकि अगर मैंने इसे कैमरे के लिए इस्तेमाल किया तो मेरा ऐप दुर्घटनाग्रस्त हो गया। मैं प्रोग्रामिंग में नया हूं और इसे हल करने के लिए 2 दिन खो गया हूं। उम्मीद है कि यह किसी की मदद करेगा।

   public String getRealPathFromURI(Uri uri) {
        if(Build.VERSION.SDK_INT >= 19){
            String id = uri.getLastPathSegment().split(":")[1];
            final String[] imageColumns = {MediaStore.Images.Media.DATA };
            final String imageOrderBy = null;
            Uri tempUri = getUri();
            Cursor imageCursor = getContentResolver().query(tempUri, imageColumns,
                    MediaStore.Images.Media._ID + "="+id, null, imageOrderBy);
            if (imageCursor.moveToFirst()) {
                return imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }else{
                return null;
            }
        }else{
            String[] projection = { MediaStore.MediaColumns.DATA };
            Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
            if (cursor != null) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            } else
                return null;
        }
    }

तो मैं अपने ExifInterface पर AtctivityResult विधि में मिलता है

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == GALLERY_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) {
        try {
            exif = new ExifInterface(getRealPathFromURI(data.getData()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        showImage(data.getData());
    } else if (requestCode == CAMERA_IMAGE_REQUEST && resultCode == RESULT_OK) {
        try {
            exif = new ExifInterface(Uri.fromFile(getCameraFile()).getPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        showImage(Uri.fromFile(getCameraFile()));
    }
}

और मेरी शो छवि विधि इस तरह दिखती है

public void showImage(Uri uri) {
    if (uri != null) {
        try {

            Bitmap bitmap = scaleBitmapDown(MediaStore.Images.Media.getBitmap(getContentResolver(), uri), IMAGE_SIZE);

            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

            bitmap = rotateBitmap(bitmap, orientation);



            if (whatPlayer.equals("Player1")) {
                mImagePlayer1.setImageBitmap(bitmap);

                bitmapPlayer1 = bitmap; //*save picture in static variable so other activity can use this
            }
            if (whatPlayer.equals("Player2")) {
                mImagePlayer2.setImageBitmap(bitmap);

                bitmapPlayer2 = bitmap;
            }

        } catch (IOException e) {
            Log.d(TAG, "Image picking failed because " + e.getMessage());
            Toast.makeText(this, R.string.image_picker_error, Toast.LENGTH_LONG).show();
        }
    } else {
        Log.d(TAG, "Image picker gave us a null image.");
        Toast.makeText(this, R.string.image_picker_error, Toast.LENGTH_LONG).show();
    }
}

मैंने हाल ही में जो सीखा है वह यह है कि यदि आप छवि का आकार बदलते हैं, तो यह आमतौर पर इसकी EXIF ​​जानकारी खो देता है। तो आप नई फाइल पुरानी EXIF ​​जानकारी देना चाहते हैं।

Source.


वास्तव में एक समस्याग्रस्त बग! मुझे यकीन नहीं है कि मुझे सुझाए गए कामकाज पसंद हैं, तो यहाँ एक और है :)

कुंजी EXTRA_OUTPUT का उपयोग EXTRA_OUTPUT और जब छवि कैप्चर की गई है तो इसे EXTRA_OUTPUT ! जाहिर है, यह केवल तभी काम करता है जब आप स्वयं फ़ाइल नाम निर्दिष्ट करने की अनुमति देते हैं।

protected void takePictureSequence() {      
    try {
        ContentValues values = new ContentValues();  
        values.put(MediaStore.Images.Media.TITLE, UUID.randomUUID().toString() + ".jpg");  
        newPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

        Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, newPhotoUri);

        startActivityForResult(intent, ActivityResults.TAKE_NEW_PICTURE_RESULT);
    } catch (Exception e) {
        Toast.makeText(this, R.string.could_not_initalize_camera, Toast.LENGTH_LONG).show();
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == ActivityResults.TAKE_NEW_PICTURE_RESULT) {
        if (resultCode == RESULT_OK) {
            try {
                String[] projection = { MediaStore.Images.Media.DATA }; 
                CursorLoader loader = new CursorLoader(this, newPhotoUri, projection, null, null, null);
                Cursor cursor = loader.loadInBackground();

                int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();

                // Rotation is stored in an EXIF tag, and this tag seems to return 0 for URIs.
                // Hence, we retrieve it using an absolute path instead!
                int rotation = 0;
                String realPath = cursor.getString(column_index_data);
                if (realPath != null) {
                    rotation = ImageHelper.getRotationForImage(realPath);
                }

                // Now we can load the bitmap from the Uri, using the correct rotation.
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public int getRotationForImage(String path) {
    int rotation = 0;

    try {
        ExifInterface exif = new ExifInterface(path);
        rotation = (int)exifOrientationToDegrees(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return rotation;
}




image-capture