CameraX কেস রোটেশন ব্যবহার করে

সঠিক ঘূর্ণন তথ্য সহ চিত্রগুলি পেতে আপনার অ্যাপের ভিতরে ক্যামেরাএক্স ব্যবহারের কেসগুলি কীভাবে সেট আপ করবেন তা এই বিষয়বস্তু প্রদর্শন করে, তা ImageAnalysis বা ImageCapture ব্যবহারের ক্ষেত্রেই হোক না কেন৷ তাই:

  • ImageAnalysis ইউজ কেস Analyzer সঠিক ঘূর্ণন সহ ফ্রেমগুলি গ্রহণ করা উচিত।
  • ImageCapture ব্যবহারের ক্ষেত্রে সঠিক ঘূর্ণন সহ ছবি তোলা উচিত।

পরিভাষা

এই বিষয়টি নিম্নলিখিত পরিভাষা ব্যবহার করে, তাই প্রতিটি শব্দের অর্থ কী তা বোঝা গুরুত্বপূর্ণ:

প্রদর্শন অভিযোজন
এটি নির্দেশ করে যে ডিভাইসের কোন দিকটি ঊর্ধ্বমুখী অবস্থানে রয়েছে এবং এটি চারটি মানগুলির মধ্যে একটি হতে পারে: প্রতিকৃতি, ল্যান্ডস্কেপ, বিপরীত প্রতিকৃতি, বা বিপরীত ল্যান্ডস্কেপ।
প্রদর্শন ঘূর্ণন
এটি Display.getRotation() দ্বারা প্রত্যাবর্তিত মান, এবং এটি সেই ডিগ্রীগুলিকে প্রতিনিধিত্ব করে যেগুলির দ্বারা ডিভাইসটিকে তার প্রাকৃতিক অভিযোজন থেকে ঘড়ির কাঁটার বিপরীতে ঘোরানো হয়৷
লক্ষ্য ঘূর্ণন
এটি ডিগ্রীর সংখ্যা প্রতিনিধিত্ব করে যার মাধ্যমে ডিভাইসটিকে ঘড়ির কাঁটার দিকে ঘোরাতে হবে তার প্রাকৃতিক অভিযোজনে পৌঁছাতে।

লক্ষ্য ঘূর্ণন কিভাবে নির্ধারণ

নিম্নলিখিত উদাহরণগুলি দেখায় যে কীভাবে একটি ডিভাইসের প্রাকৃতিক অভিযোজনের উপর ভিত্তি করে লক্ষ্য ঘূর্ণন নির্ধারণ করা যায়।

উদাহরণ 1: প্রতিকৃতি প্রাকৃতিক অভিযোজন

ডিভাইসের উদাহরণ: Pixel 3 XL

প্রাকৃতিক অভিযোজন = প্রতিকৃতি
বর্তমান অভিযোজন = প্রতিকৃতি

প্রদর্শন ঘূর্ণন = 0
লক্ষ্য ঘূর্ণন = 0

প্রাকৃতিক অভিযোজন = প্রতিকৃতি
বর্তমান অভিযোজন = ল্যান্ডস্কেপ

প্রদর্শন ঘূর্ণন = 90
লক্ষ্য ঘূর্ণন = 90

উদাহরণ 2: ল্যান্ডস্কেপ প্রাকৃতিক অভিযোজন

ডিভাইসের উদাহরণ: পিক্সেল সি

প্রাকৃতিক অভিযোজন = ল্যান্ডস্কেপ
বর্তমান অভিযোজন = ল্যান্ডস্কেপ

প্রদর্শন ঘূর্ণন = 0
লক্ষ্য ঘূর্ণন = 0

প্রাকৃতিক অভিযোজন = ল্যান্ডস্কেপ
বর্তমান অভিযোজন = প্রতিকৃতি

প্রদর্শন ঘূর্ণন = 270
লক্ষ্য ঘূর্ণন = 270

চিত্র ঘূর্ণন

কোন শেষ পর্যন্ত? সেন্সর ওরিয়েন্টেশনকে অ্যান্ড্রয়েডে একটি ধ্রুবক মান হিসাবে সংজ্ঞায়িত করা হয়েছে, যা ডিগ্রী (0, 90, 180, 270) উপস্থাপন করে যখন ডিভাইসটি স্বাভাবিক অবস্থানে থাকে তখন ডিভাইসের উপরের দিক থেকে সেন্সরটি ঘোরানো হয়। ডায়াগ্রামের সমস্ত ক্ষেত্রে, চিত্রের ঘূর্ণন বর্ণনা করে যে কীভাবে ডেটা সোজা দেখানোর জন্য ঘড়ির কাঁটার দিকে ঘোরানো উচিত।

নীচের উদাহরণগুলি দেখায় যে ক্যামেরা সেন্সর অভিযোজনের উপর নির্ভর করে চিত্রের ঘূর্ণন কেমন হওয়া উচিত। তারা লক্ষ্য ঘূর্ণন প্রদর্শন ঘূর্ণন সেট করা হয়েছে অনুমান.

উদাহরণ 1: সেন্সর 90 ডিগ্রি ঘোরে

ডিভাইসের উদাহরণ: Pixel 3 XL

প্রদর্শন ঘূর্ণন = 0
প্রদর্শন অভিযোজন = প্রতিকৃতি
চিত্র ঘূর্ণন = 90

প্রদর্শন ঘূর্ণন = 90
ডিসপ্লে ওরিয়েন্টেশন = ল্যান্ডস্কেপ
চিত্র ঘূর্ণন = 0

উদাহরণ 2: সেন্সর 270 ডিগ্রি ঘোরে

ডিভাইসের উদাহরণ: Nexus 5X

প্রদর্শন ঘূর্ণন = 0
প্রদর্শন অভিযোজন = প্রতিকৃতি
চিত্র ঘূর্ণন = 270

প্রদর্শন ঘূর্ণন = 90
ডিসপ্লে ওরিয়েন্টেশন = ল্যান্ডস্কেপ
চিত্র ঘূর্ণন = 180

উদাহরণ 3: সেন্সর 0 ডিগ্রি ঘোরে

ডিভাইসের উদাহরণ: পিক্সেল সি (ট্যাবলেট)

প্রদর্শন ঘূর্ণন = 0
ডিসপ্লে ওরিয়েন্টেশন = ল্যান্ডস্কেপ
চিত্র ঘূর্ণন = 0

প্রদর্শন ঘূর্ণন = 270
প্রদর্শন অভিযোজন = প্রতিকৃতি
চিত্র ঘূর্ণন = 90

একটি চিত্রের ঘূর্ণন গণনা

চিত্র বিশ্লেষণ

ImageAnalysis এর Analyzer ImageProxy s আকারে ক্যামেরা থেকে ছবি গ্রহণ করে। প্রতিটি ছবিতে ঘূর্ণন তথ্য রয়েছে, যা এর মাধ্যমে অ্যাক্সেসযোগ্য:

val rotation = imageProxy.imageInfo.rotationDegrees

এই মানটি সেই ডিগ্রীগুলিকে প্রতিনিধিত্ব করে যার দ্বারা চিত্রটিকে ImageAnalysis লক্ষ্য ঘূর্ণনের সাথে মেলে ঘড়ির কাঁটার দিকে ঘোরানো প্রয়োজন৷ একটি অ্যান্ড্রয়েড অ্যাপের প্রেক্ষাপটে, ImageAnalysis লক্ষ্য ঘূর্ণন সাধারণত স্ক্রীনের অভিযোজনের সাথে মেলে।

ইমেজ ক্যাপচার

একটি কলব্যাক একটি ImageCapture উদাহরণের সাথে সংযুক্ত করা হয় যখন একটি ক্যাপচার ফলাফল প্রস্তুত হয় তখন সংকেত দিতে। ফলাফল ক্যাপচার করা ছবি বা একটি ত্রুটি হতে পারে।

একটি ছবি তোলার সময়, প্রদত্ত কলব্যাক নিম্নলিখিত ধরনের হতে পারে:

  • OnImageCapturedCallback : একটি ImageProxy আকারে ইন-মেমরি অ্যাক্সেস সহ একটি চিত্র গ্রহণ করে।
  • OnImageSavedCallback : যখন ক্যাপচার করা ছবি সফলভাবে ImageCapture.OutputFileOptions দ্বারা নির্দিষ্ট স্থানে সংরক্ষণ করা হয় তখন আহ্বান করা হয়। বিকল্পগুলি একটি File , একটি OutputStream , বা MediaStore একটি অবস্থান নির্দিষ্ট করতে পারে।

ক্যাপচার করা ছবির ঘূর্ণন, তার বিন্যাস নির্বিশেষে ( ImageProxy , File , OutputStream , MediaStore Uri ) সেই ঘূর্ণন ডিগ্রীগুলিকে প্রতিনিধিত্ব করে যার দ্বারা ক্যাপচার করা ছবিটিকে ImageCapture এর লক্ষ্য ঘূর্ণনের সাথে মেলে ঘড়ির কাঁটার দিকে ঘোরানো প্রয়োজন, যা আবার, এর প্রসঙ্গে একটি অ্যান্ড্রয়েড অ্যাপ, সাধারণত স্ক্রিনের অভিযোজনের সাথে মেলে।

ক্যাপচার করা চিত্রের ঘূর্ণন পুনরুদ্ধার করা নিম্নলিখিত উপায়গুলির মধ্যে একটিতে করা যেতে পারে:

ImageProxy

val rotation = imageProxy.imageInfo.rotationDegrees

File

val exif = Exif.createFromFile(file)
val rotation = exif.rotation

OutputStream

val byteArray = outputStream.toByteArray()
val exif = Exif.createFromInputStream(ByteArrayInputStream(byteArray))
val rotation = exif.rotation

MediaStore uri

val inputStream = contentResolver.openInputStream(outputFileResults.savedUri)
val exif = Exif.createFromInputStream(inputStream)
val rotation = exif.rotation

একটি ছবির ঘূর্ণন যাচাই করুন

ImageAnalysis এবং ImageCapture ব্যবহারের ক্ষেত্রে একটি সফল ক্যাপচার অনুরোধের পরে ক্যামেরা থেকে ImageProxy গুলি গ্রহণ করা হয়। একটি ImageProxy একটি চিত্র এবং এটির ঘূর্ণন সহ এটি সম্পর্কে তথ্য মোড়ক করে। এই ঘূর্ণন তথ্যটি সেই ডিগ্রীগুলিকে প্রতিনিধিত্ব করে যার দ্বারা চিত্রটিকে ব্যবহারের ক্ষেত্রের লক্ষ্য ঘূর্ণনের সাথে মেলে ঘোরাতে হবে৷

একটি চিত্রের ঘূর্ণন যাচাইকরণ প্রবাহ

ইমেজ ক্যাপচার/ইমেজ অ্যানালাইসিস টার্গেট রোটেশন নির্দেশিকা

যেহেতু অনেক ডিভাইস রিভার্স পোর্ট্রেট বা রিভার্স ল্যান্ডস্কেপ ডিফল্টরূপে ঘোরে না, তাই কিছু অ্যান্ড্রয়েড অ্যাপ এই অভিযোজন সমর্থন করে না। একটি অ্যাপ এটিকে সমর্থন করে বা না ব্যবহার করার ক্ষেত্রের লক্ষ্য ঘূর্ণন আপডেট করার উপায় পরিবর্তন করে কিনা।

ডিসপ্লে রোটেশনের সাথে সিঙ্কে ব্যবহারের ক্ষেত্রের টার্গেট রোটেশন কীভাবে রাখা যায় তা নীচে দুটি টেবিল রয়েছে। প্রথমটি দেখায় যে চারটি অভিযোজন সমর্থন করার সময় কীভাবে তা করা যায়; দ্বিতীয়টি শুধুমাত্র ডিফল্টরূপে ডিভাইসটি ঘোরানো অভিযোজন পরিচালনা করে।

আপনার অ্যাপে কোন নির্দেশিকা অনুসরণ করতে হবে তা বেছে নিতে:

  1. আপনার অ্যাপের ক্যামেরা Activity লক করা ওরিয়েন্টেশন, আনলক করা ওরিয়েন্টেশন আছে কিনা বা এটি ওরিয়েন্টেশন কনফিগারেশন পরিবর্তন ওভাররাইড করে কিনা তা যাচাই করুন।

  2. আপনার অ্যাপের ক্যামেরা Activity চারটি ডিভাইস ওরিয়েন্টেশন (পোর্ট্রেট, রিভার্স পোর্ট্রেট, ল্যান্ডস্কেপ এবং রিভার্স ল্যান্ডস্কেপ) পরিচালনা করবে কিনা বা এটি ডিফল্টরূপে যে ডিভাইসটি সমর্থন করে তাতে শুধুমাত্র ওরিয়েন্টেশন পরিচালনা করা উচিত কিনা তা নির্ধারণ করুন।

সব চারটি অভিযোজন সমর্থন

এই সারণীতে নির্দিষ্ট নির্দেশিকা উল্লেখ করা হয়েছে যে ক্ষেত্রে ডিভাইসটি বিপরীত প্রতিকৃতিতে ঘোরে না। একইটি এমন ডিভাইসগুলিতে প্রয়োগ করা যেতে পারে যেগুলি বিপরীত ল্যান্ডস্কেপে ঘোরে না।

দৃশ্যকল্প নির্দেশিকা একক-উইন্ডো মোড মাল্টি-উইন্ডো স্প্লিট-স্ক্রিন মোড
আনলক করা অভিযোজন প্রতিবার Activity তৈরি করার সময় ব্যবহারের ক্ষেত্রে সেট আপ করুন, যেমন Activity onCreate() কলব্যাকে।
OrientationEventListener এর onOrientationChanged() ব্যবহার করুন। কলব্যাকের ভিতরে, ব্যবহারের ক্ষেত্রে লক্ষ্য ঘূর্ণন আপডেট করুন। এটি এমন ক্ষেত্রে পরিচালনা করে যেখানে সিস্টেমটি একটি স্থিতি পরিবর্তনের পরেও Activity পুনরায় তৈরি করে না, যেমন যখন ডিভাইসটি 180 ডিগ্রি ঘোরানো হয়। ডিসপ্লেটি যখন বিপরীত প্রতিকৃতি অভিযোজনে থাকে এবং ডিভাইসটি ডিফল্টরূপে বিপরীত প্রতিকৃতিতে ঘোরে না তখনও পরিচালনা করে। এছাড়াও এমন ক্ষেত্রে পরিচালনা করে যেখানে ডিভাইসটি ঘোরার সময় Activity পুনরায় তৈরি করা হয় না (উদাহরণস্বরূপ 90 ডিগ্রি)। এটি ছোট ফর্ম ফ্যাক্টর ডিভাইসগুলিতে ঘটে যখন অ্যাপটি অর্ধেক স্ক্রীন নেয় এবং বড় ডিভাইসে যখন অ্যাপটি স্ক্রীনের দুই তৃতীয়াংশ দখল করে।
ঐচ্ছিক: AndroidManifest ফাইলে Activity screenOrientation প্রপার্টি fullSensor সেট করুন। যখন ডিভাইসটি বিপরীত প্রতিকৃতিতে থাকে তখন এটি UI-কে খাড়া থাকার অনুমতি দেয় এবং যখনই ডিভাইসটি 90 ডিগ্রি ঘোরানো হয় তখন সিস্টেম দ্বারা Activity পুনরায় তৈরি করার অনুমতি দেয়। যে ডিভাইসগুলি ডিফল্টরূপে বিপরীত প্রতিকৃতিতে ঘোরে না সেগুলিতে কোনও প্রভাব নেই৷ মাল্টি-উইন্ডো মোড সমর্থিত নয় যখন ডিসপ্লেটি বিপরীত পোর্ট্রেট ওরিয়েন্টেশনে থাকে।
লক করা অভিযোজন শুধুমাত্র একবার ব্যবহারের ক্ষেত্রে সেট আপ করুন, যখন Activity প্রথম তৈরি করা হয়, যেমন Activity onCreate() কলব্যাকে।
OrientationEventListener এর onOrientationChanged() ব্যবহার করুন। কলব্যাকের ভিতরে, পূর্বরূপ ব্যতীত ব্যবহারের ক্ষেত্রে লক্ষ্য ঘূর্ণন আপডেট করুন। এছাড়াও এমন ক্ষেত্রে পরিচালনা করে যেখানে ডিভাইসটি ঘোরার সময় Activity পুনরায় তৈরি করা হয় না (উদাহরণস্বরূপ 90 ডিগ্রি)। এটি ছোট ফর্ম ফ্যাক্টর ডিভাইসগুলিতে ঘটে যখন অ্যাপটি অর্ধেক স্ক্রীন নেয় এবং বড় ডিভাইসে যখন অ্যাপটি স্ক্রীনের দুই তৃতীয়াংশ দখল করে।
অভিযোজন কনফিগার পরিবর্তনগুলি ওভাররাইড করা হয়েছে৷ শুধুমাত্র একবার ব্যবহারের ক্ষেত্রে সেট আপ করুন, যখন Activity প্রথম তৈরি করা হয়, যেমন Activity onCreate() কলব্যাকে।
OrientationEventListener এর onOrientationChanged() ব্যবহার করুন। কলব্যাকের ভিতরে, ব্যবহারের ক্ষেত্রে লক্ষ্য ঘূর্ণন আপডেট করুন। এছাড়াও এমন ক্ষেত্রে পরিচালনা করে যেখানে ডিভাইসটি ঘোরার সময় Activity পুনরায় তৈরি করা হয় না (উদাহরণস্বরূপ 90 ডিগ্রি)। এটি ছোট ফর্ম ফ্যাক্টর ডিভাইসগুলিতে ঘটে যখন অ্যাপটি অর্ধেক স্ক্রীন নেয় এবং বড় ডিভাইসে যখন অ্যাপটি স্ক্রীনের দুই তৃতীয়াংশ দখল করে।
ঐচ্ছিক: AndroidManifest ফাইলে অ্যাক্টিভিটির স্ক্রীন ওরিয়েন্টেশন প্রপার্টি ফুল সেন্সরে সেট করুন। যখন ডিভাইসটি বিপরীত প্রতিকৃতিতে থাকে তখন UI কে খাড়া থাকার অনুমতি দেয়। যে ডিভাইসগুলি ডিফল্টরূপে বিপরীত প্রতিকৃতিতে ঘোরে না সেগুলিতে কোনও প্রভাব নেই৷ মাল্টি-উইন্ডো মোড সমর্থিত নয় যখন ডিসপ্লেটি বিপরীত পোর্ট্রেট ওরিয়েন্টেশনে থাকে।

শুধুমাত্র ডিভাইস-সমর্থিত ওরিয়েন্টেশন সমর্থন করে

ডিভাইসটি ডিফল্টরূপে সমর্থন করে শুধুমাত্র অভিযোজন সমর্থন করে (যাতে বিপরীত প্রতিকৃতি/বিপরীত ল্যান্ডস্কেপ অন্তর্ভুক্ত থাকতে পারে বা নাও থাকতে পারে)।

দৃশ্যকল্প নির্দেশিকা মাল্টি-উইন্ডো স্প্লিট-স্ক্রিন মোড
আনলক করা অভিযোজন প্রতিবার Activity তৈরি করার সময় ব্যবহারের ক্ষেত্রে সেট আপ করুন, যেমন Activity onCreate() কলব্যাকে।
DisplayListener এর onDisplayChanged() ব্যবহার করুন। কলব্যাকের ভিতরে, ব্যবহারের ক্ষেত্রে লক্ষ্য ঘূর্ণন আপডেট করুন, যেমন যখন ডিভাইসটি 180 ডিগ্রি ঘোরানো হয়। এছাড়াও এমন ক্ষেত্রে পরিচালনা করে যেখানে ডিভাইসটি ঘোরার সময় Activity পুনরায় তৈরি করা হয় না (উদাহরণস্বরূপ 90 ডিগ্রি)। এটি ছোট ফর্ম ফ্যাক্টর ডিভাইসগুলিতে ঘটে যখন অ্যাপটি অর্ধেক স্ক্রীন নেয় এবং বড় ডিভাইসে যখন অ্যাপটি স্ক্রীনের দুই তৃতীয়াংশ দখল করে।
লক করা অভিযোজন শুধুমাত্র একবার ব্যবহারের ক্ষেত্রে সেট আপ করুন, যখন Activity প্রথম তৈরি করা হয়, যেমন Activity onCreate() কলব্যাকে।
OrientationEventListener এর onOrientationChanged() ব্যবহার করুন। কলব্যাকের ভিতরে, ব্যবহারের ক্ষেত্রে লক্ষ্য ঘূর্ণন আপডেট করুন। এছাড়াও এমন ক্ষেত্রে পরিচালনা করে যেখানে ডিভাইসটি ঘোরার সময় Activity পুনরায় তৈরি করা হয় না (উদাহরণস্বরূপ 90 ডিগ্রি)। এটি ছোট ফর্ম ফ্যাক্টর ডিভাইসগুলিতে ঘটে যখন অ্যাপটি অর্ধেক স্ক্রীন নেয় এবং বড় ডিভাইসে যখন অ্যাপটি স্ক্রীনের দুই তৃতীয়াংশ দখল করে।
অভিযোজন কনফিগার পরিবর্তনগুলি ওভাররাইড করা হয়েছে৷ শুধুমাত্র একবার ব্যবহারের ক্ষেত্রে সেট আপ করুন, যখন Activity প্রথম তৈরি করা হয়, যেমন Activity onCreate() কলব্যাকে।
DisplayListener এর onDisplayChanged() ব্যবহার করুন। কলব্যাকের ভিতরে, ব্যবহারের ক্ষেত্রে লক্ষ্য ঘূর্ণন আপডেট করুন, যেমন যখন ডিভাইসটি 180 ডিগ্রি ঘোরানো হয়। এছাড়াও এমন ক্ষেত্রে পরিচালনা করে যেখানে ডিভাইসটি ঘোরার সময় Activity পুনরায় তৈরি করা হয় না (উদাহরণস্বরূপ 90 ডিগ্রি)। এটি ছোট ফর্ম ফ্যাক্টর ডিভাইসগুলিতে ঘটে যখন অ্যাপটি অর্ধেক স্ক্রীন নেয় এবং বড় ডিভাইসে যখন অ্যাপটি স্ক্রীনের দুই তৃতীয়াংশ দখল করে।

আনলক করা অভিযোজন

একটি Activity একটি আনলক করা অভিযোজন থাকে যখন এটির প্রদর্শন অভিযোজন (যেমন প্রতিকৃতি বা ল্যান্ডস্কেপ) ডিভাইসের শারীরিক অভিযোজনের সাথে মেলে, বিপরীত প্রতিকৃতি/ল্যান্ডস্কেপ বাদে, যা কিছু ডিভাইস ডিফল্টরূপে সমর্থন করে না। ডিভাইসটিকে চারটি অভিযোজনে ঘোরাতে বাধ্য করতে, Activity screenOrientation বৈশিষ্ট্যটিকে fullSensor সেট করুন।

মাল্টি-উইন্ডো মোডে, ডিফল্টরূপে বিপরীত প্রতিকৃতি/ল্যান্ডস্কেপ সমর্থন করে না এমন একটি ডিভাইস বিপরীত পোর্ট্রেট/ল্যান্ডস্কেপে ঘুরবে না, এমনকি যখন এর screenOrientation প্রপার্টি fullSensor সেট করা থাকে।

<!-- The Activity has an unlocked orientation, but might not rotate to reverse
portrait/landscape in single-window mode if the device doesn't support it by
default. -->
<activity android:name=".UnlockedOrientationActivity" />

<!-- The Activity has an unlocked orientation, and will rotate to all four
orientations in single-window mode. -->
<activity
   android:name=".UnlockedOrientationActivity"
   android:screenOrientation="fullSensor" />

লক করা অভিযোজন

একটি ডিসপ্লেতে একটি লক করা ওরিয়েন্টেশন থাকে যখন এটি একই ডিসপ্লে ওরিয়েন্টেশনে থাকে (যেমন পোর্ট্রেট বা ল্যান্ডস্কেপ) ডিভাইসের ফিজিক্যাল ওরিয়েন্টেশন নির্বিশেষে। এটি AndroidManifest.xml ফাইলে একটি Activity screenOrientation বৈশিষ্ট্য উল্লেখ করার মাধ্যমে করা যেতে পারে।

যখন ডিসপ্লেতে একটি লক করা অভিযোজন থাকে, ডিভাইসটি ঘোরানোর সাথে সাথে সিস্টেমটি Activity ধ্বংস করে না এবং পুনরায় তৈরি করে না।

<!-- The Activity keeps a portrait orientation even as the device rotates. -->
<activity
   android:name=".LockedOrientationActivity"
   android:screenOrientation="portrait" />

ওরিয়েন্টেশন কনফিগারেশন পরিবর্তন ওভাররাইড করা হয়েছে

যখন কোনো Activity ওভাররাইড করে ওরিয়েন্টেশন কনফিগারেশন পরিবর্তন করে, ডিভাইসের ফিজিক্যাল ওরিয়েন্টেশন পরিবর্তিত হলে সিস্টেম এটিকে ধ্বংস করে না এবং পুনরায় তৈরি করে না। ডিভাইসের শারীরিক অভিযোজনের সাথে মেলে যদিও সিস্টেমটি UI আপডেট করে।

<!-- The Activity's UI might not rotate in reverse portrait/landscape if the
device doesn't support it by default. -->
<activity
   android:name=".OrientationConfigChangesOverriddenActivity"
   android:configChanges="orientation|screenSize" />

<!-- The Activity's UI will rotate to all 4 orientations in single-window
mode. -->
<activity
   android:name=".OrientationConfigChangesOverriddenActivity"
   android:configChanges="orientation|screenSize"
   android:screenOrientation="fullSensor" />

ক্যামেরা ব্যবহার কেস সেটআপ

উপরে বর্ণিত পরিস্থিতিতে, ক্যামেরা ব্যবহারের কেসগুলি সেট আপ করা যেতে পারে যখন Activity প্রথম তৈরি করা হয়।

আনলক করা অভিযোজন সহ একটি Activity ক্ষেত্রে, এই সেটআপটি প্রতিবার ডিভাইসটি ঘোরানোর সময় করা হয়, কারণ সিস্টেম অভিযোজন পরিবর্তনের Activity ধ্বংস করে এবং পুনরায় তৈরি করে। এর ফলে ব্যবহারের ক্ষেত্রে প্রতিবার ডিফল্টরূপে ডিসপ্লের ওরিয়েন্টেশনের সাথে মেলে তাদের লক্ষ্য ঘূর্ণন সেট করে।

একটি লক করা অভিযোজন সহ একটি Activity ক্ষেত্রে বা অভিযোজন কনফিগারেশন পরিবর্তনগুলিকে ওভাররাইড করে, এই সেটআপটি একবার করা হয়, যখন Activity প্রথম তৈরি করা হয়৷

class CameraActivity : AppCompatActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)

       val cameraProcessFuture = ProcessCameraProvider.getInstance(this)
       cameraProcessFuture.addListener(Runnable {
          val cameraProvider = cameraProcessFuture.get()

          // By default, the use cases set their target rotation to match the
          // display’s rotation.
          val preview = buildPreview()
          val imageAnalysis = buildImageAnalysis()
          val imageCapture = buildImageCapture()

          cameraProvider.bindToLifecycle(
              this, cameraSelector, preview, imageAnalysis, imageCapture)
       }, mainExecutor)
   }
}

ওরিয়েন্টেশন ইভেন্টলিসনার সেটআপ

একটি OrientationEventListener ব্যবহার করে ডিভাইসের অভিযোজন পরিবর্তনের সাথে সাথে ক্যামেরা ব্যবহারের ক্ষেত্রের লক্ষ্য ঘূর্ণন ক্রমাগত আপডেট করতে পারবেন।

class CameraActivity : AppCompatActivity() {

    private val orientationEventListener by lazy {
        object : OrientationEventListener(this) {
            override fun onOrientationChanged(orientation: Int) {
                if (orientation == ORIENTATION_UNKNOWN) {
                    return
                }

                val rotation = when (orientation) {
                     in 45 until 135 -> Surface.ROTATION_270
                     in 135 until 225 -> Surface.ROTATION_180
                     in 225 until 315 -> Surface.ROTATION_90
                     else -> Surface.ROTATION_0
                 }

                 imageAnalysis.targetRotation = rotation
                 imageCapture.targetRotation = rotation
            }
        }
    }

    override fun onStart() {
        super.onStart()
        orientationEventListener.enable()
    }

    override fun onStop() {
        super.onStop()
        orientationEventListener.disable()
    }
}

ডিসপ্লে লিস্টেনার সেটআপ

একটি DisplayListener ব্যবহার করে আপনি নির্দিষ্ট পরিস্থিতিতে ক্যামেরা ব্যবহারের ক্ষেত্রের টার্গেট ঘূর্ণন আপডেট করতে পারবেন, উদাহরণস্বরূপ যখন ডিভাইসটি 180 ডিগ্রি ঘোরার পরে সিস্টেমটি Activity ধ্বংস করে না এবং পুনরায় তৈরি করে না।

class CameraActivity : AppCompatActivity() {

    private val displayListener = object : DisplayManager.DisplayListener {
        override fun onDisplayChanged(displayId: Int) {
            if (rootView.display.displayId == displayId) {
                val rotation = rootView.display.rotation
                imageAnalysis.targetRotation = rotation
                imageCapture.targetRotation = rotation
            }
        }

        override fun onDisplayAdded(displayId: Int) {
        }

        override fun onDisplayRemoved(displayId: Int) {
        }
    }

    override fun onStart() {
        super.onStart()
        val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
        displayManager.registerDisplayListener(displayListener, null)
    }

    override fun onStop() {
        super.onStop()
        val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
        displayManager.unregisterDisplayListener(displayListener)
    }
}