অ্যান্ড্রয়েড: গ্যালারী থেকে লোড বিটম্যাপগুলি ইমেজভিউতে ঘোরানো হয়


138

আমি যখন মিডিয়া গ্যালারী থেকে কোনও বিটম্যাপে কোনও চিত্র লোড করি তখন ফোনটি উল্লম্বভাবে ধরে রাখার সময় ক্যামেরা দিয়ে গুলি করা ছবিগুলি বাদ দিয়ে সবকিছু ঠিকঠাক করা হয় যাতে আমি সর্বদা একটি অনুভূমিক চিত্র পেতে পারি যদিও এটি উল্লম্বভাবে প্রদর্শিত হয় গ্যালারি। এটি কেন এবং আমি কীভাবে এটি সঠিকভাবে লোড করতে পারি?


আমি বাস্তব উত্তর আছে stackoverflow.com/questions/29971319/image-orientation-android/...
A.Sanchez.SD

উত্তর:


40

আপনি কি চিত্রগুলির এক্সআইএফ ডেটা দেখেছেন? এটি যখন ছবিটি নেওয়া হয়েছিল তখন এটি ক্যামেরার অরিয়েন্টেশন জানতে পারে।


2
আপনি ঠিক বলেছেন, অবশ্যই সমাধান ছিল। আমি আমার কোডটি একটি পৃথক উত্তরে উদাহরণ হিসাবে পোস্ট করব, পরে, তবে আমি এটিটিকে স্বীকৃত হিসাবে চিহ্নিত করি কারণ এটি আমাকে সঠিক পথে পেয়েছে।
ম্যানুয়েল

182

সুতরাং, একটি উদাহরণ হিসাবে ...

প্রথমে আপনাকে একটি এক্সিফাইনটারফেস তৈরি করতে হবে:

ExifInterface exif = new ExifInterface(filename);

তারপরে আপনি চিত্রটির ওরিয়েন্টেশনটি দখল করতে পারেন:

orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

ওরিয়েন্টেশন মানগুলি কী বোঝায় তা এখানে: http://sylvana.net/jpegcrop/exif_orientation.html

সুতরাং, সর্বাধিক গুরুত্বপূর্ণ মানগুলি হ'ল 3, 6 এবং 8। ExifInterface.ORIENTATION_ROTATE_90উদাহরণস্বরূপ, যদি ওরিয়েন্টেশন হয় (যা 6 হয়) তবে আপনি চিত্রটি এইভাবে ঘোরান:

Matrix matrix = new Matrix();
matrix.postRotate(90);
rotatedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);

যদিও এটি একটি চটজলদি উদাহরণ। আমি নিশ্চিত প্রকৃত ঘূর্ণন সম্পাদন করার অন্যান্য উপায় আছে। তবে আপনি স্ট্যাকওভারফ্লোতে সেগুলিও পাবেন।


5
বিভিন্ন ওরিয়েন্টেশনের জন্য এখানে সমস্ত ঘোরানোর মান রয়েছে: 3: 180, 6: 90, 8: 270
নাম প্রদর্শন

103
নামযুক্ত ধ্রুবকগুলি ব্যবহার করতে পারলে যাদু নম্বর ব্যবহার করবেন না: ExifInterface.ORIENTATION_NORMAL, ExifInterface.ORIENTATION_ROTATE_90, ExifInterface.ORIENTATION_ROTATE_180, ExifInterface.ORIENTATION_ROTATE_270।
d60402

29
এর থেকে সাবধান OutOfMemoryErrorযখন এই পদ্ধতির ব্যবহার আপনি একই সময়ে মেমরি দুই বিটম্যাপ ধরে রাখুন।
অ্যালেক্স বনেল

আর একটি সম্পূর্ণ উদাহরণ ... স্ট্যাকওভারফ্লো
জিজ্ঞাসা /

64

এটি একটি সম্পূর্ণ সমাধান (ফেসবুক এসডিকে হ্যাকবুকের উদাহরণে পাওয়া যায়)। এটি নিজেই ফাইল অ্যাক্সেস প্রয়োজন না করার সুবিধা আছে। আপনি যদি বিষয়বস্তু সমাধানের জিনিস থেকে কোনও চিত্র লোড করছেন তবে এটি অত্যন্ত দরকারী eg

public static int getOrientation(Context context, Uri photoUri) {
    /* it's on the external media. */
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);

    if (cursor.getCount() != 1) {
        return -1;
    }

    cursor.moveToFirst();
    return cursor.getInt(0);
}

এবং তারপরে আপনি নিম্নরূপে ঘোরানো বিটম্যাপটি পেতে পারেন। এই কোডটি চিত্রটিকে (দুর্ভাগ্যবশত দুর্ভাগ্যক্রমে) MAX_IMAGE_DIMENSION পর্যন্ত স্কেল করে। অন্যথায় আপনি স্মৃতিশক্তি শেষ হতে পারে।

public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException {
    InputStream is = context.getContentResolver().openInputStream(photoUri);
    BitmapFactory.Options dbo = new BitmapFactory.Options();
    dbo.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, dbo);
    is.close();

    int rotatedWidth, rotatedHeight;
    int orientation = getOrientation(context, photoUri);

    if (orientation == 90 || orientation == 270) {
        rotatedWidth = dbo.outHeight;
        rotatedHeight = dbo.outWidth;
    } else {
        rotatedWidth = dbo.outWidth;
        rotatedHeight = dbo.outHeight;
    }

    Bitmap srcBitmap;
    is = context.getContentResolver().openInputStream(photoUri);
    if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
        float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
        float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
        float maxRatio = Math.max(widthRatio, heightRatio);

        // Create the bitmap from file
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = (int) maxRatio;
        srcBitmap = BitmapFactory.decodeStream(is, null, options);
    } else {
        srcBitmap = BitmapFactory.decodeStream(is);
    }
    is.close();

    /*
     * if the orientation is not 0 (or -1, which means we don't know), we
     * have to do a rotation.
     */
    if (orientation > 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(orientation);

        srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
                srcBitmap.getHeight(), matrix, true);
    }

    return srcBitmap;
}

1
এই MAX_IMAGE_DIMENDION এর অর্থ কী?
সাজ্জাদ হিছাইন খান

3
এটি আপনার পাওয়া চিত্রের সর্বোচ্চ প্রস্থ বা উচ্চতা। অর্থ্যাৎ আপনার কেবল একটি 512x512 চিত্রের প্রয়োজন, আপনি যদি কোনও 24 মেগাপিক্সেল চিত্র খোলেন তবে পুরো বিষয়টি খোলার চেয়ে ইতিমধ্যে সাবমলড খোলার পক্ষে এটি আরও দক্ষ এবং এটি স্কেল করে ফেলুন - এটি সম্ভবত আপনার সমস্ত স্মৃতি সরিয়ে দেবে।
টিম্ম্ম্ম

আমার প্রোগ্রামগুলিতে আমি বিটিম্যাপ ভেরিয়েবলটিকে ক্রিয়াকলাপ / টুকরোটিতে ব্যক্তিগত স্ট্যাটিক হিসাবে সংজ্ঞায়িত করতে এবং কার্যকার্যগুলিতে এটিকে শূন্য করতে সেটাকে দরকারী বলে মনে করি। স্মৃতিশক্তি কম ছিল তখন।
গুন্নার বার্নস্টেইন

MAX_IMAGE_DIMENDION কে MAX_IMAGE_WIDTH এবং MAX_IMAGE_HEIGHT
fnc12

আমার অনেক সময় বাঁচিয়েছে :) অনেক ধন্যবাদ। নাল কার্সার পেয়ে তাদের জন্য, আপনি চেষ্টা করতে পারেন ExifInterface exif = new ExifInterface(photoUri.getPath());এবং তারপর exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1)অভিযোজন পেতে (যেমন ORIENTATION_ROTATE_90, ORIENTATION_ROTATE_180)
অতুল

60

এই পোস্টের সাহায্য ব্যবহার করে এই কোডটি দিয়ে আমার ক্ষেত্রে এটি সমাধান করুন:

            Bitmap myBitmap = getBitmap(imgFile.getAbsolutePath());

            try {
                ExifInterface exif = new ExifInterface(imgFile.getAbsolutePath());
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
                Log.d("EXIF", "Exif: " + orientation);
                Matrix matrix = new Matrix();
                if (orientation == 6) {
                    matrix.postRotate(90);
                }
                else if (orientation == 3) {
                    matrix.postRotate(180);
                }
                else if (orientation == 8) {
                    matrix.postRotate(270);
                }
                myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true); // rotating bitmap
            }
            catch (Exception e) {

            }
            ImageView img = (ImageView) findViewById(R.id.imgTakingPic);
            img.setImageBitmap(myBitmap);

আশা করি এটি কারও সময় বাঁচায়!


পরামর্শগুলি সম্পাদনা করুন:,,,, the পদক্ষেপের জন্য কোনও সঠিক নামকরণের ধ্রুবক নেই? কোনও ঘূর্ণন প্রয়োজন না হলে আমরা কী নতুন বিটম্যাপটি এড়িয়ে যেতে পারি না?
সিই ম্যাকশারফেস

@ D60402 যেমন পূর্বে একটি মন্তব্যে বলেছিল, আপনি নামযুক্ত ধ্রুবকগুলি ব্যবহার করতে পারেন: ExifInterface.ORIENTATION_NORMAL, ExifInterface.ORIENTATION_ROTATE_90, ExifInterface.ORIENTATION_ROTATE_180, ExifInterface.ORIENTATION_ROTATE_270।
অ্যাড্রিয়ান

42

ভারী উত্তোলন করতে একটি ইউটিলিটি ব্যবহার করুন।

9 এক্স এক্সআইএফ ডেটা নিয়ে কাজ করার ভারী উত্তোলন এবং চিত্রগুলিকে তাদের সঠিক দিকনির্দেশের দিকে ঘোরানোর জন্য একটি সাধারণ ইউটিলিটি তৈরি করেছে।

আপনি এখানে ইউটিলিটি কোডটি পেতে পারেন: https://gist.github.com/9re/1990019

কেবল এটি ডাউনলোড করুন, এটি আপনার প্রকল্পের srcডিরেক্টরিতে যুক্ত করুন এবং ExifUtil.rotateBitmap()সঠিক দিকনির্দেশনা পেতে ব্যবহার করুন :

String imagePath = photoFile.getAbsolutePath();             // photoFile is a File class.
Bitmap myBitmap  = BitmapFactory.decodeFile(imagePath);

Bitmap orientedBitmap = ExifUtil.rotateBitmap(imagePath, myBitmap);

2
আমার জন্য কাজ কর ! আমি এইভাবে আউটঅফমিওরিরর এড়ানোর জন্য ExifUtil.rotateBitmap () এ যাওয়ার আগে বিটম্যাপটিকে এইচডি ফর্ম্যাটে পুনরায় আকার দিয়েছি: বিটম্যাপ পুনরায় আকার দেওয়া = বিটম্যাপ ক্রিয়েটস্কেলবিটম্যাপ (আমার বিটম্যাপ, 720, 1280, সত্য); ফটো = এক্সিফটাইল.রোটেট বিটম্যাপ (চিত্রপথ, পুনরায় আকার দেওয়া);
ফিল

@ ফিল ভালো লাগা। আমি এতে প্রবেশ করি নি (আমি পুরানো, শিটটিয়ার অ্যান্ড্রয়েড ডিভাইসগুলি ব্যবহার করছি) তবে এটি জেনে রাখা সত্যিই ভাল।
জোশুয়া পিন্টার

3
আপনি একজন নায়ক আমার বন্ধু :)
ক্লাচ

@ ক্লাচ আপনি আমার দিনটি সবেমাত্র তৈরি করেছেন। :) সত্যি কথা বলতে, 9re ইউটিলিটি কোডটি লিখেছিল যাতে সে আসল নায়ক।
জোশুয়া পিন্টার

1
@ শ্রীকান্ত কারুমানঘাট দুর্দান্ত প্রশ্ন! আমি সম্ভবত জানতাম কেন আমি যখন এটির গভীরে ছিলাম তখন কেন এটি বোধগম্য হয়েছিল তবে এখনই এটি আমার পক্ষেও অপ্রয়োজনীয় বলে মনে হয়। রিয়েট নেটিভে সম্ভবত খুব বেশি সময় ব্যয় করা হয়েছে।
জোশুয়া পিন্টার 13

8

এর কারণ গ্যালারীটি সঠিকভাবে ঘোরানো চিত্র প্রদর্শন করছে তবে চিত্র ভিউ নয় এখানে:

                    myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(),optionss);
                    ExifInterface exif = new ExifInterface(selectedImagePath);
                    int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                    int rotationInDegrees = exifToDegrees(rotation);
                    deg = rotationInDegrees;
                    Matrix matrix = new Matrix();
                    if (rotation != 0f) {
                        matrix.preRotate(rotationInDegrees);
                        myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true);
                    }

এবং আপনার এটি দরকার:

private static int exifToDegrees(int exifOrientation) {        
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } 
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {  return 180; } 
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {  return 270; }            
    return 0;    
} 

5

অনেক চেষ্টা করার পরেও এটি কাজ করতে পেরেছি এমন পোস্টের জন্য ধন্যবাদ আমি আর খুঁজে পাচ্ছি না :-(

এক্সিফ সবসময় কাজ করে বলে মনে হয়, ফাইলপ্যাথ পেতে অসুবিধা হয়েছিল। আমি যে কোডটি পেয়েছি তা এপিআই-এর মধ্যে 4.4 এর চেয়ে পুরানো এবং 4.4 এর পরে আলাদা হয়। মূলত 4.4+ এর জন্য ইউআরআই ছবিতে "com.android.provider" রয়েছে। এই জাতীয় ইউআরআই-এর জন্য কোড আইডিটি পেতে ডকুমেন্টস কনট্র্যাক্ট ব্যবহার করে এবং তারপরে কনটেন্ট রিসোলভার ব্যবহার করে একটি কোয়েরি চালায়, পুরানো এসডিকে-র জন্য কোডটি সরাসরি কন্টেন্টআরসলভারের সাথে ইউআরআইকে জিজ্ঞাসা করে।

এখানে কোডটি রয়েছে (দুঃখিত আমি এটি পোস্ট করে ক্রেডিট করতে পারি না):

/**
 * Handles pre V19 uri's
 * @param context
 * @param contentUri
 * @return
 */
public static String getPathForPreV19(Context context, Uri contentUri) {
    String res = null;

    String[] proj = { MediaStore.Images.Media.DATA };
    Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
    if(cursor.moveToFirst()){;
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        res = cursor.getString(column_index);
    }
    cursor.close();

    return res;
}

/**
 * Handles V19 and up uri's
 * @param context
 * @param contentUri
 * @return path
 */
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPathForV19AndUp(Context context, Uri contentUri) {
    String wholeID = DocumentsContract.getDocumentId(contentUri);

    // Split at colon, use second item in the array
    String id = wholeID.split(":")[1];
    String[] column = { MediaStore.Images.Media.DATA };

    // where id is equal to
    String sel = MediaStore.Images.Media._ID + "=?";
    Cursor cursor = context.getContentResolver().
            query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    column, sel, new String[]{ id }, null);

    String filePath = "";
    int columnIndex = cursor.getColumnIndex(column[0]);
    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }

    cursor.close();
    return filePath;
}

public static String getRealPathFromURI(Context context,
        Uri contentUri) {
    String uriString = String.valueOf(contentUri);
    boolean goForKitKat= uriString.contains("com.android.providers");

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && goForKitKat) {
            Log.i("KIKAT","YES");
            return getPathForV19AndUp(context, contentUri);
        } else {

            return getPathForPreV19(context, contentUri);
        }
}

আপনার জন্য অনেক ধন্যবাদ। কার্সার এবং এক্সিফসের সাথে কয়েক ঘন্টা কাজ করার পরে, এই দিনটি সংরক্ষিত হতে পারে। যেমনটি আপনি বলেছেন, বাস্তবে এক্সিফের কার্সার রিটার্নের পরিবর্তে সত্য এবং নির্ভরযোগ্য ডেটা রয়েছে। এটি কাজ করার চেয়ে সঠিক পথ দিন।
asozcan

3

আপনি কেবল এসডি কার্ড থেকে পাথটি পড়তে পারেন এবং নীচের কোডটি করতে পারেন ... এটি বিদ্যমান ফটোটি ঘোরার পরে প্রতিস্থাপন করবে ..

নয়: এক্সিফ বেশিরভাগ ডিভাইসে কাজ করে না, এটি ভুল ডেটা দেয় তাই আপনার যে ডিগ্রিটি সংরক্ষণ করতে চান তার আগে সংরক্ষণের আগে হার্ড কোডটি ঘোরানো ভাল, আপনাকে কেবল পোস্টরোটে কোণ মান পরিবর্তন করতে হবে আপনি যে কোনওটিকে চান।

    String photopath = tempphoto.getPath().toString();
    Bitmap bmp = BitmapFactory.decodeFile(photopath);

    Matrix matrix = new Matrix();
    matrix.postRotate(90);
    bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);

    FileOutputStream fOut;
    try {
        fOut = new FileOutputStream(tempphoto);
        bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
        fOut.flush();
        fOut.close();

    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

2
এটি ঘোরাতে হয় তবে আমরা জানি না ইমেজের ঘোরানোর দরকার আছে কিনা।
এমএসউডি

3

কোটলিন কোড:

if (file.exists()){
    val bitmap = BitmapFactory.decodeFile(file.absolutePath)

    val exif = ExifInterface(file.absoluteFile.toString())
    val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
    val matrix = Matrix()

    when(orientation){
        ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90F)
        ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180F)
        ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270F)
    }

    val rotatedBitmap = Bitmap.createBitmap(bitmap, 0,0 , bitmap.width, bitmap.height, matrix, true)
    bitmap.recycle()
    iv_capture.setImageBitmap(rotatedBitmap)
}

2

টিও ইঙ্কের উত্তরে আমি উন্নতি করেছি। এটি চিত্রটির আর প্রয়োজনীয় পরিবর্তন না করে এদিকে আর ঘোরায় না। এটি পড়াও সহজ এবং দ্রুত চালানো উচিত।

// Load Image
Bitmap bitmap = BitmapFactory.decodeFile(filePath);

// Rotate Image if Needed
try
{
    // Determine Orientation
    ExifInterface exif = new ExifInterface(filePath);
    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

    // Determine Rotation
    int rotation = 0;
    if      (orientation == 6)      rotation = 90;
    else if (orientation == 3)      rotation = 180;
    else if (orientation == 8)      rotation = 270;

    // Rotate Image if Necessary
    if (rotation != 0)
    {
        // Create Matrix
        Matrix matrix = new Matrix();
        matrix.postRotate(rotation);

        // Rotate Bitmap
        Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 

        // Pretend none of this ever happened!
        bitmap.recycle();
        bitmap = rotated;
        rotated = null;
     }
}
catch (Exception e)
{
    // TODO: Log Error Messages Here
}

// TODO: Use Result Here
xxx.setBitmap(bitmap);

2

আপনার প্রথম যেটি দরকার তা হ'ল আসল ফাইল পাথ যদি আপনার যদি এটি দুর্দান্ত থাকে তবে আপনি যদি ইউআরআই ব্যবহার করে থাকেন তবে আসল পথটি পেতে এই পদ্ধতিটি ব্যবহার করুন:

 public static String getRealPathFromURI(Uri contentURI,Context context) {
    String path= contentURI.getPath();
    try {
        Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null);
        cursor.moveToFirst();
        String document_id = cursor.getString(0);
        document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
        cursor.close();

        cursor = context.getContentResolver().query(
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
        cursor.moveToFirst();
        path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        cursor.close();
    }
    catch(Exception e)
    {
        return path;
    }
    return path;
}

উদাহরণস্বরূপ আপনার বিটম্যাপটি বের করুন:

  try {
                            Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);

                        }
                        catch (IOException e)
                        {
                            Log.e("IOException",e.toString());
                        }

আপনি যদি চান তবে ডিকোডফিল () ব্যবহার করতে পারেন।

এখন আপনার কাছে বিটম্যাপ এবং আসল পথ চিত্রটির ওরিয়েন্টেশন পেয়েছে:

 private static int getExifOrientation(String src) throws IOException {
        int orientation = 1;

        ExifInterface exif = new ExifInterface(src);
        String orientationString=exif.getAttribute(ExifInterface.TAG_ORIENTATION);
        try {
            orientation = Integer.parseInt(orientationString);
        }
        catch(NumberFormatException e){}

        return orientation;
    }

এবং অবশেষে এটিকে সঠিক অবস্থানে ঘোরান:

public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
        try {
            int orientation = getExifOrientation(src);

            if (orientation == 1) {
                return bitmap;
            }

            Matrix matrix = new Matrix();
            switch (orientation) {
                case 2:
                    matrix.setScale(-1, 1);
                    break;
                case 3:
                    matrix.setRotate(180);
                    break;
                case 4:
                    matrix.setRotate(180);
                    matrix.postScale(-1, 1);
                    break;
                case 5:
                    matrix.setRotate(90);
                    matrix.postScale(-1, 1);
                    break;
                case 6:
                    matrix.setRotate(90);
                    break;
                case 7:
                    matrix.setRotate(-90);
                    matrix.postScale(-1, 1);
                    break;
                case 8:
                    matrix.setRotate(-90);
                    break;
                default:
                    return bitmap;
            }

            try {
                Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                bitmap.recycle();
                return oriented;
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

এটি এখন আপনার বিটম্যাপটি সঠিক অবস্থানে ঘোরানো to

চিয়ার্স।


1

এটি কাজ করে তবে সম্ভবত এটি করার সর্বোত্তম উপায় নয় তবে এটি কারওর পক্ষে সহায়তা করতে পারে।

String imagepath = someUri.getAbsolutePath();
imageview = (ImageView)findViewById(R.id.imageview);
imageview.setImageBitmap(setImage(imagepath, 120, 120));    

public Bitmap setImage(String path, final int targetWidth, final int targetHeight) {
    Bitmap bitmap = null;
// Get exif orientation     
    try {
        ExifInterface exif = new ExifInterface(path);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
        if (orientation == 6) {
            orientation_val = 90;
        }
        else if (orientation == 3) {
            orientation_val = 180;
        }
        else if (orientation == 8) {
            orientation_val = 270;
        }
    }
        catch (Exception e) {
        }

        try {
// First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, options);

// Adjust extents
            int sourceWidth, sourceHeight;
            if (orientation_val == 90 || orientation_val == 270) {
                sourceWidth = options.outHeight;
                sourceHeight = options.outWidth;
            } else {
                sourceWidth = options.outWidth;
                sourceHeight = options.outHeight;
            }

// Calculate the maximum required scaling ratio if required and load the bitmap
            if (sourceWidth > targetWidth || sourceHeight > targetHeight) {
                float widthRatio = (float)sourceWidth / (float)targetWidth;
                float heightRatio = (float)sourceHeight / (float)targetHeight;
                float maxRatio = Math.max(widthRatio, heightRatio);
                options.inJustDecodeBounds = false;
                options.inSampleSize = (int)maxRatio;
                bitmap = BitmapFactory.decodeFile(path, options);
            } else {
                bitmap = BitmapFactory.decodeFile(path);
            }

// Rotate the bitmap if required
            if (orientation_val > 0) {
                Matrix matrix = new Matrix();
                matrix.postRotate(orientation_val);
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            }

// Re-scale the bitmap if necessary
            sourceWidth = bitmap.getWidth();
            sourceHeight = bitmap.getHeight();
            if (sourceWidth != targetWidth || sourceHeight != targetHeight) {
                float widthRatio = (float)sourceWidth / (float)targetWidth;
                float heightRatio = (float)sourceHeight / (float)targetHeight;
                float maxRatio = Math.max(widthRatio, heightRatio);
                sourceWidth = (int)((float)sourceWidth / maxRatio);
                sourceHeight = (int)((float)sourceHeight / maxRatio);
                bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth,     sourceHeight, true);
            }
        } catch (Exception e) {
        }
        return bitmap;
    }

1

সম্ভবত এটি সাহায্য করবে (90 ডিগ্রি ঘোরান) (এটি আমার জন্য কাজ করেছে)

private Bitmap rotateBitmap(Bitmap image){
        int width=image.getHeight();
        int height=image.getWidth();

        Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig());

        for (int y=width-1;y>=0;y--)
            for(int x=0;x<height;x++)
                srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y));
        return srcBitmap;

    }

1

কার্সারটি এটি খোলার পরে বন্ধ করা উচিত।

এখানে একটি উদাহরণ।

 public static int getOrientation(Context context, Uri selectedImage)
{
    int orientation = -1;
    Cursor cursor = context.getContentResolver().query(selectedImage,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
    if (cursor.getCount() != 1)
       return orientation;

    cursor.moveToFirst();
    orientation = cursor.getInt(0);
    cursor.close(); // ADD THIS LINE
   return orientation;
}

1

আমি @ টিম্মিম উত্তর এবং @ ম্যানুয়েল গলিয়েছি। আপনি যদি এই সমাধানটি করেন তবে আপনি রান আউট অফ মেমরি ব্যতিক্রম পাবেন না।

এই পদ্ধতিটি চিত্রের ওরিয়েন্টেশনটি পুনরুদ্ধার করে:

private static final int ROTATION_DEGREES = 90;
// This means 512 px
private static final Integer MAX_IMAGE_DIMENSION = 512;

public static int getOrientation(Uri photoUri) throws IOException {

    ExifInterface exif = new ExifInterface(photoUri.getPath());
    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            orientation = ROTATION_DEGREES;
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            orientation = ROTATION_DEGREES * 2;
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            orientation = ROTATION_DEGREES * 3;
            break;
        default:
            // Default case, image is not rotated
            orientation = 0;
    }

    return orientation;
}

সুতরাং, আপনি মেমরিতে লোড করার আগে চিত্রটিকে পুনরায় আকার দেওয়ার জন্য এই পদ্ধতিটি ব্যবহার করবেন। এইভাবে, আপনি কোনও স্মৃতি ব্যতিক্রম পাবেন না।

public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException {
    InputStream is = context.getContentResolver().openInputStream(photoUri);
    BitmapFactory.Options dbo = new BitmapFactory.Options();
    dbo.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, dbo);
    is.close();

    int rotatedWidth, rotatedHeight;
    int orientation = getOrientation(photoUri);

    if (orientation == 90 || orientation == 270) {
        rotatedWidth = dbo.outHeight;
        rotatedHeight = dbo.outWidth;
    } else {
        rotatedWidth = dbo.outWidth;
        rotatedHeight = dbo.outHeight;
    }

    Bitmap srcBitmap;
    is = context.getContentResolver().openInputStream(photoUri);
    if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
        float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
        float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
        float maxRatio = Math.max(widthRatio, heightRatio);

        // Create the bitmap from file
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = (int) maxRatio;
        srcBitmap = BitmapFactory.decodeStream(is, null, options);
    } else {
        srcBitmap = BitmapFactory.decodeStream(is);
    }
    is.close();

    // if the orientation is not 0, we have to do a rotation.
    if (orientation > 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(orientation);

        srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
                srcBitmap.getHeight(), matrix, true);
    }

    return srcBitmap;
}

এটি আমার পক্ষে নিখুঁতভাবে কাজ করে। আমি আশা করি এটি অন্য কাউকে সাহায্য করবে


0

চিত্রটি সীমানার মধ্যে ফিট করে কিনা তা নিশ্চিত করার জন্য টিম্ম্ম্ম দ্বারা উপরের সমাধানটি উন্নত করে শেষে কিছু অতিরিক্ত স্কেলিং যুক্ত করুন:

public static Bitmap loadBitmap(String path, int orientation, final int targetWidth, final int targetHeight) {
    Bitmap bitmap = null;
    try {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Adjust extents
        int sourceWidth, sourceHeight;
        if (orientation == 90 || orientation == 270) {
            sourceWidth = options.outHeight;
            sourceHeight = options.outWidth;
        } else {
            sourceWidth = options.outWidth;
            sourceHeight = options.outHeight;
        }

        // Calculate the maximum required scaling ratio if required and load the bitmap
        if (sourceWidth > targetWidth || sourceHeight > targetHeight) {
            float widthRatio = (float)sourceWidth / (float)targetWidth;
            float heightRatio = (float)sourceHeight / (float)targetHeight;
            float maxRatio = Math.max(widthRatio, heightRatio);
            options.inJustDecodeBounds = false;
            options.inSampleSize = (int)maxRatio;
            bitmap = BitmapFactory.decodeFile(path, options);
        } else {
            bitmap = BitmapFactory.decodeFile(path);
        }

        // Rotate the bitmap if required
        if (orientation > 0) {
            Matrix matrix = new Matrix();
            matrix.postRotate(orientation);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }

        // Re-scale the bitmap if necessary
        sourceWidth = bitmap.getWidth();
        sourceHeight = bitmap.getHeight();
        if (sourceWidth != targetWidth || sourceHeight != targetHeight) {
            float widthRatio = (float)sourceWidth / (float)targetWidth;
            float heightRatio = (float)sourceHeight / (float)targetHeight;
            float maxRatio = Math.max(widthRatio, heightRatio);
            sourceWidth = (int)((float)sourceWidth / maxRatio);
            sourceHeight = (int)((float)sourceHeight / maxRatio);
            bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true);
        }
    } catch (Exception e) {
    }
    return bitmap;
}

0

কোনও চিত্র সঠিকভাবে আবর্তিত করতে নিম্নলিখিত কোডটি ব্যবহার করুন:

private Bitmap rotateImage(Bitmap bitmap, String filePath)
{
    Bitmap resultBitmap = bitmap;

    try
    {
        ExifInterface exifInterface = new ExifInterface(filePath);
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

        Matrix matrix = new Matrix();

        if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
        {
            matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_90);
        }
        else if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
        {
            matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_180);
        }
        else if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
        {
            matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_270);
        }

        // Rotate the bitmap
        resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }
    catch (Exception exception)
    {
        Logger.d("Could not rotate the image");
    }
    return resultBitmap;
}

শর্তগুলি এক সাথে একটি ছোট কোডের জন্য একত্রিত করতে পারেন।
চন্দ্রনশু

0

আঁশ এবং নীচের পদ্ধতিগুলি অরিয়েন্টেশন অনুসারে বিটম্যাপটি ঘোরায়:

public Bitmap scaleAndRotateImage(String path, int orientation, final int targetWidth, final int targetHeight)
{
    Bitmap bitmap = null;

    try
    {
        // Check the dimensions of the Image
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Adjust the Width and Height
        int sourceWidth, sourceHeight;
        if (orientation == 90 || orientation == 270)
        {
            sourceWidth = options.outHeight;
            sourceHeight = options.outWidth;
        }
        else
        {
            sourceWidth = options.outWidth;
            sourceHeight = options.outHeight;
        }

        // Calculate the maximum required scaling ratio if required and load the bitmap
        if (sourceWidth > targetWidth || sourceHeight > targetHeight)
        {
            float widthRatio = (float)sourceWidth / (float)targetWidth;
            float heightRatio = (float)sourceHeight / (float)targetHeight;
            float maxRatio = Math.max(widthRatio, heightRatio);
            options.inJustDecodeBounds = false;
            options.inSampleSize = (int)maxRatio;
            bitmap = BitmapFactory.decodeFile(path, options);
        }
        else
        {
            bitmap = BitmapFactory.decodeFile(path);
        }

        // We need to rotate the bitmap (if required)
        int orientationInDegrees = exifToDegrees(orientation);
        if (orientation > 0)
        {
            Matrix matrix = new Matrix();
            if (orientation != 0f)
            {
                matrix.preRotate(orientationInDegrees);
            };

            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }

        // Re-scale the bitmap if necessary
        sourceWidth = bitmap.getWidth();
        sourceHeight = bitmap.getHeight();

        if (sourceWidth != targetWidth || sourceHeight != targetHeight)
        {
            float widthRatio = (float)sourceWidth / (float)targetWidth;
            float heightRatio = (float)sourceHeight / (float)targetHeight;
            float maxRatio = Math.max(widthRatio, heightRatio);
            sourceWidth = (int)((float)sourceWidth / maxRatio);
            sourceHeight = (int)((float)sourceHeight / maxRatio);
            bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true);
        }
    }
    catch (Exception e)
    {
        Logger.d("Could not rotate the image");
        Logger.d(e.getMessage());
    }
    return bitmap;
}

উদাহরণ:

public void getPictureFromDevice(Uri Uri,ImageView imageView)
{
    try
    {
        ExifInterface exifInterface = new ExifInterface(Uri.getPath());
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        Bitmap bitmap = scaleAndRotateImage(Uri.getPath(), orientation, imageView.getWidth(), imageView.getHeight());
        imageView.setImageBitmap(bitmap);
    }
    catch (OutOfMemoryError outOfMemoryError)
    {
        Logger.d(outOfMemoryError.getLocalizedMessage());
        Logger.d("Failed to load image from filePath (out of memory)");
        Logger.d(Uri.toString());
    }
    catch (Exception e)
    {
        Logger.d("Failed to load image from filePath");
        Logger.d(Uri.toString());
    }
}

-3

নিম্নলিখিত সমস্যাগুলি সমাধান করে সমস্যাটি সমাধান করেছি। নোট করুন যে আমি চিত্রটিও স্কেলিং করছি, যা আউটঅফমিউরিএক্সেপশনগুলি এড়াতে প্রয়োজনীয় ছিল।

সাবধান যে এই সমাধানটি প্রতিকৃতি চিত্র বা ওপসাইড-ডাউন চিত্রগুলির সাথে সঠিকভাবে কাজ করবে না (লক্ষ করার জন্য টিম্ম্মকে ধন্যবাদ)। উপরের টিমমিএমের সমাধানটি যদি প্রয়োজন হয় তবে এটি আরও ভাল পছন্দ হতে পারে এবং এটি আরও মার্জিত দেখায়: https://stackoverflow.com/a/8914291/449918

File path = // ... location of your bitmap file
int w = 512; int h = 384; // size that does not lead to OutOfMemoryException on Nexus One
Bitmap b = BitmapFactory.decodeFile(path);


// Hack to determine whether the image is rotated
boolean rotated = b.getWidth() > b.getHeight();

Bitmap resultBmp = null;

// If not rotated, just scale it
if (!rotated) {
    resultBmp = Bitmap.createScaledBitmap(b, w, h, true);
    b.recycle();
    b = null;

// If rotated, scale it by switching width and height and then rotated it
} else {
    Bitmap scaledBmp = Bitmap.createScaledBitmap(b, h, w, true);
    b.recycle();
    b = null;

    Matrix mat = new Matrix();
    mat.postRotate(90);
    resultBmp = Bitmap.createBitmap(scaledBmp, 0, 0, h, w, mat, true);

    // Release image resources
    scaledBmp.recycle();
    scaledBmp = null;
}

// resultBmp now contains the scaled and rotated image

চিয়ার্স


এটি সঠিকভাবে কাজ করছে না। প্রতিকৃতি চিত্র সম্পর্কে কি? উপরের দিকের চিত্রগুলি? এক্সিফ ডেটা ব্যবহার করা আরও ভাল।
টিএমএমএম

এটি আমার একটি অ্যাপ্লিকেশনটিতে সঠিকভাবে কাজ করে তবে অবশ্যই আমি সব ধরণের পরিস্থিতি পরীক্ষা করে দেখিনি। @ টিম্ম্ম্মাম আপনি দয়া করে কোন পরিস্থিতিতে এটি কাজ করে না তার মধ্যে আরও নির্দিষ্ট হতে পারেন? আপনি আমার পোস্টটি নিচে ভোট দেওয়ার বিষয়েও আমি বেশ বিস্মিত। কোনও সম্ভাব্য সমাধান ভাগ করে নেওয়ার সৎ চেষ্টা করার পক্ষে এটি বেশ কঠোর প্রতিক্রিয়া বলে মনে হচ্ছে।
মার্টিন

আমি কঠোর হতে চাইনি; দুঃখিত! আমি কেবল চাইনি যে কেউ আপনার সমাধানটি কাজ করবে আশা করে অনুলিপি করবেন। যেমনটি আমি বলেছি, এটি প্রতিকৃতি বা উল্টোপাল্ট চিত্রগুলির জন্য কাজ করবে না। আমি উত্তর হিসাবে সঠিক সমাধান যোগ করব।
টিম্ম্ম্ম

আমি দেখি. আমি উপরের পছন্দ হিসাবে আপনার সমাধান হাইলাইট একটি মন্তব্য যোগ করব।
মার্টিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.