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




image-capture (4)

इसके लिए मेरा समाधान। एलजी जी 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();
    }
}

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


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

Source.


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

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);
    }

ठीक है दोस्तों, ऐसा लगता है कि एंड्रॉइड के लिए इस बग को थोड़ी देर के लिए तय नहीं किया जाएगा। हालांकि मुझे ExifInformation को लागू करने का एक तरीका मिला है, ताकि दोनों डिवाइस (उचित Exif टैग वाले, और अनुचित exif टैग एक साथ काम करते हैं) ..

तो समस्या कुछ (नए) उपकरणों पर है, एक बग है जो आपके ऐप फ़ोल्डर में उचित एक्फिफ़ टैग के बिना सहेजी गई तस्वीर को बनाता है, जबकि एंड्रॉइड डिफ़ॉल्ट फ़ोल्डर में ठीक से घुमाए गए चित्र को सहेजा जाता है (भले ही यह नहीं होना चाहिए)। ।

अब मैं क्या करता हूं, मैं उस समय को रिकॉर्ड करता हूं जब मैं अपने ऐप से कैमरा ऐप शुरू कर रहा हूं। गतिविधि परिणाम पर, मैं मीडिया प्रदाता से पूछता हूं कि यह सहेजा गया है कि मैंने सहेजे गए इस टाइमस्टैम्प के बाद कोई चित्र सहेजा गया था या नहीं। इसका मतलब है कि, सबसे अधिक संभावना ओएस ने डिफ़ॉल्ट फ़ोल्डर में सही ढंग से घूर्णन वाली तस्वीर को सहेज लिया और निश्चित रूप से मीडिया स्टोर में प्रवेश दर्ज किया और हम इस पंक्ति से रोटेशन जानकारी का उपयोग कर सकते हैं। अब यह सुनिश्चित करने के लिए कि हम सही छवि को देख रहे हैं, मैं इस फ़ाइल के आकार की तुलना उस व्यक्ति से करता हूं जिस पर मुझे पहुंच है (मेरे अपने ऐप फ़ोल्डर में सहेजा गया है);

    int rotation =-1;
    long fileSize = new File(filePath).length();

    Cursor mediaCursor = content.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] {MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE }, MediaStore.MediaColumns.DATE_ADDED + ">=?", new String[]{String.valueOf(captureTime/1000 - 1)}, MediaStore.MediaColumns.DATE_ADDED + " desc");

    if (mediaCursor != null && captureTime != 0 && mediaCursor.getCount() !=0 ) {
        while(mediaCursor.moveToNext()){
            long size = mediaCursor.getLong(1);
            //Extra check to make sure that we are getting the orientation from the proper file
            if(size == fileSize){
                rotation = mediaCursor.getInt(0);
                break;
            }
        }
    }

अब अगर इस बिंदु पर घूर्णन अभी भी -1 है, तो इसका मतलब है कि यह उचित घूर्णन जानकारी वाले फोनों में से एक है। इस बिंदु पर, हम उस फ़ाइल पर नियमित एक्सिफ़ अभिविन्यास का उपयोग कर सकते हैं जो हमारे AtctivityResult पर वापस आ गया है

    else if(rotation == -1){
        rotation = getExifOrientationAttribute(filePath);
    }

आप आसानी से पता लगा सकते हैं कि इस प्रश्न में उत्तर जैसे एक्सिफ ओरिएंटेशन को एंड्रॉइड में कैमरा अभिविन्यास समस्या कैसे प्राप्त करें

यह भी ध्यान रखें कि ExifInterface केवल एपीआई स्तर 5 के बाद समर्थित है .. इसलिए यदि आप 2.0 से पहले फोन का समर्थन करना चाहते हैं, तो आप ड्रू नोएक्स के जावा सौजन्य के लिए पाए गए इस आसान लाइब्रेरी का उपयोग कर सकते हैं; http://www.drewnoakes.com/code/exif/

घुमावदार अपनी छवि के साथ शुभकामनाएँ!

संपादित करें: क्योंकि यह पूछा गया था, मैंने जिस इरादे का उपयोग किया है और मैंने कैसे शुरू किया वह इस तरह था

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//mediaFile is where the image will be saved
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
startActivityForResult(intent, 1);






image-capture