ক্যামেরা ওরিয়েন্টেশন

যদি আপনার অ্যান্ড্রয়েড অ্যাপ ক্যামেরা ব্যবহার করে, তাহলে ওরিয়েন্টেশন পরিচালনা করার সময় কিছু বিশেষ বিবেচনা রয়েছে। এই ডকুমেন্টটি ধরে নেয় যে আপনি অ্যান্ড্রয়েড camera2 এপিআই-এর মৌলিক ধারণাগুলি বুঝতে পেরেছেন। ক্যামেরা২-এর একটি সারসংক্ষেপের জন্য আপনি আমাদের ব্লগ পোস্ট বা সারাংশ পড়তে পারেন। আমরা আপনাকে এই ডকুমেন্টটি ব্যবহার করার আগে প্রথমে একটি ক্যামেরা অ্যাপ লেখার চেষ্টা করার পরামর্শ দিচ্ছি।

পটভূমি

অ্যান্ড্রয়েড ক্যামেরা অ্যাপগুলিতে ওরিয়েন্টেশন পরিচালনা করা জটিল এবং নিম্নলিখিত বিষয়গুলি বিবেচনায় নেওয়া প্রয়োজন:

  • প্রাকৃতিক ওরিয়েন্টেশন: ডিভাইস ডিজাইনের জন্য যখন ডিভাইসটি 'স্বাভাবিক' অবস্থানে থাকে তখন ডিসপ্লে ওরিয়েন্টেশন - সাধারণত মোবাইল ফোনের জন্য পোর্ট্রেট ওরিয়েন্টেশন এবং ল্যাপটপের জন্য ল্যান্ডস্কেপ ওরিয়েন্টেশন।
  • সেন্সর ওরিয়েন্টেশন: ডিভাইসে শারীরিকভাবে মাউন্ট করা সেন্সরের ওরিয়েন্টেশন।
  • ডিসপ্লে ঘূর্ণন: প্রাকৃতিক অভিযোজন থেকে ডিভাইসটি কতটা ভৌতভাবে ঘোরানো হয়েছে।
  • ভিউফাইন্ডারের আকার: ক্যামেরা প্রিভিউ প্রদর্শনের জন্য ব্যবহৃত ভিউফাইন্ডারের আকার।
  • ক্যামেরা দ্বারা ছবির আকার আউটপুট।

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

জিনিসগুলিকে আরও সহজ করার জন্য, ধরে নিন যে সমস্ত উদাহরণে একটি পিছনের দিকের ক্যামেরা রয়েছে যদি না অন্যথায় উল্লেখ করা হয়। এছাড়াও, নিম্নলিখিত সমস্ত ছবিগুলি দৃশ্যত স্পষ্ট করার জন্য সিমুলেটেড করা হয়েছে।

ওরিয়েন্টেশন সম্পর্কে সবকিছু

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

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

পর্যবেক্ষক পক্ষ থেকে একটি ফোন, একটি ল্যাপটপ এবং একটি বস্তু সহ প্রাকৃতিক অভিযোজনের চিত্রণ

সেন্সর ওরিয়েন্টেশন

আনুষ্ঠানিকভাবে বলতে গেলে, সেন্সর ওরিয়েন্টেশন পরিমাপ করা হয় ডিভাইসের স্বাভাবিক ওরিয়েন্টেশনের সাথে মেলে সেন্সর থেকে আউটপুট ইমেজকে ঘড়ির কাঁটার দিকে ঘোরানোর ডিগ্রি দ্বারা। অন্য কথায়, সেন্সর ওরিয়েন্টেশন হল ডিভাইসে মাউন্ট করার আগে সেন্সরকে ঘড়ির কাঁটার বিপরীত দিকে ঘোরানোর ডিগ্রির সংখ্যা। স্ক্রিনের দিকে তাকালে, ঘূর্ণন ঘড়ির কাঁটার দিকে বলে মনে হয়, কারণ রিয়ার-ক্যামেরা সেন্সরটি ডিভাইসের "পিছনের" দিকে ইনস্টল করা আছে।

অ্যান্ড্রয়েড ১০ কম্প্যাটিবিলিটি ডেফিনিশন ৭.৫.৫ ক্যামেরা ওরিয়েন্টেশন অনুসারে, সামনের এবং পিছনের ক্যামেরাগুলিকে "এমনভাবে ওরিয়েন্টেড করতে হবে যাতে ক্যামেরার লম্বা মাত্রা স্ক্রিনের লম্বা মাত্রার সাথে সামঞ্জস্যপূর্ণ হয়।"

ক্যামেরার আউটপুট বাফারগুলি ল্যান্ডস্কেপ-আকারের হয়। যেহেতু ফোনের প্রাকৃতিক ওরিয়েন্টেশন সাধারণত পোর্ট্রেট হয়, তাই সেন্সর ওরিয়েন্টেশন সাধারণত প্রাকৃতিক ওরিয়েন্টেশন থেকে 90 বা 270 ডিগ্রি হয় যাতে আউটপুট বাফারের লম্বা দিকটি স্ক্রিনের লম্বা দিকের সাথে মিলে যায়। যেসব ডিভাইসের প্রাকৃতিক ওরিয়েন্টেশন ল্যান্ডস্কেপ, যেমন Chromebook, তাদের ক্ষেত্রে সেন্সর ওরিয়েন্টেশন আলাদা। এই ডিভাইসগুলিতে, চিত্র সেন্সরগুলি আবার স্থাপন করা হয় যাতে আউটপুট বাফারের লম্বা দিকটি স্ক্রিনের লম্বা দিকের সাথে মিলে যায়। যেহেতু এই উভয়ই ল্যান্ডস্কেপ-আকারের, ওরিয়েন্টেশনগুলি মিলে যায় এবং সেন্সর ওরিয়েন্টেশন 0 বা 180 ডিগ্রি হয়।

পর্যবেক্ষক পক্ষ থেকে একটি ফোন, একটি ল্যাপটপ এবং একটি বস্তু সহ প্রাকৃতিক অভিযোজনের চিত্রণ

নিম্নলিখিত চিত্রগুলি দেখায় যে ডিভাইসের স্ক্রিনের দিকে তাকিয়ে একজন পর্যবেক্ষকের দৃষ্টিকোণ থেকে জিনিসগুলি কেমন দেখায়:

পর্যবেক্ষক পক্ষ থেকে একটি ফোন, একটি ল্যাপটপ এবং একটি বস্তু সহ সেন্সর ওরিয়েন্টেশন চিত্রণ

নিম্নলিখিত দৃশ্যটি বিবেচনা করুন:

একটি সুন্দর অ্যান্ড্রয়েড মূর্তি (বাগড্রয়েড) সহ একটি দৃশ্য

ফোন ল্যাপটপ
ফোনের পিছনের ক্যামেরা সেন্সরের মধ্য দিয়ে দেখার ছবির চিত্র।ল্যাপটপে পিছনের ক্যামেরা সেন্সরের মধ্য দিয়ে দেখার চিত্র।

যেহেতু ফোনে সেন্সর ওরিয়েন্টেশন সাধারণত 90 বা 270 ডিগ্রি হয়, সেন্সর ওরিয়েন্টেশনের হিসাব না করে, আপনি যে ছবিগুলি পাবেন তা এইরকম দেখাবে:

ফোন ল্যাপটপ
ফোনের পিছনের ক্যামেরা সেন্সরের মধ্য দিয়ে দেখার ছবির চিত্র।ল্যাপটপে পিছনের ক্যামেরা সেন্সরের মধ্য দিয়ে দেখার চিত্র।

ধরুন, সেন্সর ওরিয়েন্টেশন ভেরিয়েবল সেন্সর ওরিয়েন্টেশনে সংরক্ষিত আছে। সেন্সর ওরিয়েন্টেশনের ক্ষতিপূরণ দিতে, আপনাকে আউটপুট বাফারগুলিকে `sensorOrientation` ঘড়ির কাঁটার দিকে ঘোরাতে হবে যাতে ডিভাইসের স্বাভাবিক ওরিয়েন্টেশনের সাথে ওরিয়েন্টেশনটি আবার সারিবদ্ধ হয়।

অ্যান্ড্রয়েডে, অ্যাপগুলি তাদের ক্যামেরা প্রিভিউ প্রদর্শনের জন্য TextureView বা SurfaceView ব্যবহার করতে পারে। অ্যাপগুলি সঠিকভাবে ব্যবহার করলে উভয়ই সেন্সর ওরিয়েন্টেশন পরিচালনা করতে পারে। নিম্নলিখিত বিভাগগুলিতে আমরা সেন্সর ওরিয়েন্টেশনের জন্য কীভাবে হিসাব করা উচিত তা বিস্তারিতভাবে বর্ণনা করব।

ডিসপ্লে রোটেশন

ডিসপ্লে ঘূর্ণন আনুষ্ঠানিকভাবে স্ক্রিনে আঁকা গ্রাফিক্সের ঘূর্ণন দ্বারা সংজ্ঞায়িত করা হয়, যা ডিভাইসের প্রাকৃতিক অভিযোজন থেকে ভৌত ঘূর্ণনের বিপরীত দিক। নিম্নলিখিত বিভাগগুলি ধরে নেয় যে ডিসপ্লে ঘূর্ণনগুলি 90 এর গুণিতক। যদি আপনি ডিসপ্লে ঘূর্ণনকে এর পরম ডিগ্রি দ্বারা পুনরুদ্ধার করেন, তাহলে এটিকে {0, 90, 180, 270} এর নিকটতম পর্যন্ত পূর্ণ করুন।

নিম্নলিখিত বিভাগগুলিতে "ডিসপ্লে ওরিয়েন্টেশন" বলতে বোঝায় যে কোনও ডিভাইসটি ল্যান্ডস্কেপ বা পোর্ট্রেট অবস্থানে শারীরিকভাবে ধরে রাখা হয়েছে এবং "ডিসপ্লে রোটেশন" থেকে আলাদা।

ধরুন আপনি ডিভাইসগুলিকে পূর্ববর্তী অবস্থান থেকে ঘড়ির কাঁটার বিপরীত দিকে 90 ডিগ্রি ঘোরান, যেমনটি নিম্নলিখিত চিত্রে দেখানো হয়েছে:

পর্যবেক্ষক পক্ষ থেকে একটি ফোন, একটি ল্যাপটপ এবং একটি বস্তু সহ 90-ডিগ্রি ডিসপ্লে ঘূর্ণন চিত্রণ

ধরে নিচ্ছি যে সেন্সর ওরিয়েন্টেশনের উপর ভিত্তি করে আউটপুট বাফারগুলি ইতিমধ্যেই ঘোরানো হয়েছে, তাহলে আপনার নিম্নলিখিত আউটপুট বাফারগুলি থাকবে:

ফোন ল্যাপটপ
ফোনের পিছনের ক্যামেরা সেন্সরের মধ্য দিয়ে দেখার ছবির চিত্র।ল্যাপটপে পিছনের ক্যামেরা সেন্সরের মধ্য দিয়ে দেখার চিত্র।

যদি ডিসপ্লে রোটেশনটি displayRotation ভেরিয়েবলে সংরক্ষিত থাকে, তাহলে সঠিক চিত্র পেতে, আপনাকে displayRotation কে ঘড়ির কাঁটার বিপরীত দিকে আউটপুট বাফারগুলি ঘোরাতে হবে।

সামনের ক্যামেরার ক্ষেত্রে, ডিসপ্লে রোটেশন স্ক্রিনের বিপরীত দিকে ইমেজ বাফারের উপর কাজ করে। যদি আপনি সামনের ক্যামেরা নিয়ে কাজ করেন, তাহলে আপনার ডিসপ্লে রোটেশন ঘড়ির কাঁটার দিকে করে বাফারগুলি ঘোরানো উচিত।

সতর্কতা

ডিসপ্লে রোটেশন ডিভাইসের ঘড়ির কাঁটার বিপরীত দিকের ঘূর্ণন পরিমাপ করে। এটি সমস্ত ওরিয়েন্টেশন/রোটেশন API-এর ক্ষেত্রে সত্য নয়।

উদাহরণস্বরূপ,

  • যদি আপনি Display#getRotation() ব্যবহার করেন, তাহলে আপনি এই ডকুমেন্টে উল্লিখিত ঘড়ির কাঁটার বিপরীত দিকে ঘূর্ণন পাবেন।
  • যদি আপনি OrientationEventListener#onOrientationChanged(int) ব্যবহার করেন, তাহলে আপনি ঘড়ির কাঁটার দিকে ঘূর্ণন পাবেন।

এখানে গুরুত্বপূর্ণ বিষয় হলো, ডিসপ্লের ঘূর্ণন প্রাকৃতিক অভিমুখের সাথে সম্পর্কিত। উদাহরণস্বরূপ, যদি আপনি একটি ফোনকে 90 বা 270 ডিগ্রি ঘোরান, তাহলে আপনি একটি ল্যান্ডস্কেপ আকৃতির স্ক্রিন পাবেন। তুলনামূলকভাবে, যদি আপনি একটি ল্যাপটপকে একই পরিমাণে ঘোরান, তাহলে আপনি একটি প্রতিকৃতি আকৃতির স্ক্রিন পাবেন। অ্যাপগুলির সর্বদা এটি মনে রাখা উচিত এবং কোনও ডিভাইসের প্রাকৃতিক অভিমুখ সম্পর্কে কখনও অনুমান করা উচিত নয়।

উদাহরণ

পূর্ববর্তী চিত্রগুলি ব্যবহার করে ওরিয়েন্টেশন এবং ঘূর্ণন কী তা বোঝানো যাক।

একটি ফোন এবং একটি ল্যাপটপ ঘোরানো ছাড়াই এবং একটি বস্তুর সাথে সম্মিলিত ওরিয়েন্টেশন চিত্রণ

ফোন ল্যাপটপ
প্রাকৃতিক অভিযোজন = প্রতিকৃতি প্রাকৃতিক অভিযোজন = ভূদৃশ্য
সেন্সর ওরিয়েন্টেশন = 90 সেন্সর ওরিয়েন্টেশন = 0
ডিসপ্লে রোটেশন = ০ ডিসপ্লে রোটেশন = ০
ডিসপ্লে ওরিয়েন্টেশন = পোর্ট্রেট ডিসপ্লে ওরিয়েন্টেশন = ল্যান্ডস্কেপ

একটি ফোন এবং একটি ল্যাপটপ ঘোরানো ছাড়াই এবং একটি বস্তুর সাথে সম্মিলিত ওরিয়েন্টেশন চিত্রণ

ফোন ল্যাপটপ
প্রাকৃতিক অভিযোজন = প্রতিকৃতি প্রাকৃতিক অভিযোজন = ভূদৃশ্য
সেন্সর ওরিয়েন্টেশন = 90 সেন্সর ওরিয়েন্টেশন = 0
ডিসপ্লে রোটেশন = ৯০ ডিসপ্লে রোটেশন = ৯০
ডিসপ্লে ওরিয়েন্টেশন = ল্যান্ডস্কেপ ডিসপ্লে ওরিয়েন্টেশন = পোর্ট্রেট

ভিউফাইন্ডারের আকার

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

ক্যামেরা অনুসারে ছবির আউটপুট আকার

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

JPEG ওরিয়েন্টেশন

চলুন শুরু করা যাক একটি সাধারণ পরিস্থিতি দিয়ে - একটি JPEG ছবি তোলা। camera2 API-তে, আপনি আপনার আউটপুট JPEG গুলিকে ঘড়ির কাঁটার দিকে কতটা ঘোরাতে চান তা নির্দিষ্ট করার জন্য ক্যাপচার অনুরোধে JPEG_ORIENTATION পাস করতে পারেন।

আমরা যা উল্লেখ করেছি তার একটি সংক্ষিপ্ত বিবরণ:

  • সেন্সর ওরিয়েন্টেশন পরিচালনা করতে, আপনাকে sensorOrientation ঘড়ির কাঁটার দিকে ইমেজ বাফার ঘোরাতে হবে।
  • ডিসপ্লে রোটেশন পরিচালনা করার জন্য, আপনাকে পিছনের ক্যামেরার জন্য displayRotation মাধ্যমে একটি বাফার ঘোরাতে হবে, ঘড়ির কাঁটার বিপরীতে এবং সামনের ক্যামেরার জন্য ঘড়ির কাঁটার দিকে।

দুটি গুণনীয়ক যোগ করলে, আপনি যে পরিমাণ ঘড়ির কাঁটার দিকে ঘোরাতে চান তা হল

  • sensorOrientation - displayRotation
  • সামনের ক্যামেরার জন্য sensorOrientation + displayRotation

এই লজিকের নমুনা কোডটি আপনি JPEG_ORIENTATION ডকুমেন্টেশনে দেখতে পাবেন। মনে রাখবেন যে ডকুমেন্টেশনের নমুনা কোডে deviceOrientation ডিভাইসের ঘড়ির কাঁটার দিকে ঘূর্ণন ব্যবহার করছে। তাই ডিসপ্লে ঘূর্ণনের জন্য চিহ্নগুলি বিপরীত।

প্রিভিউ

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

সারফেসভিউ

সারফেসভিউ সাধারণত ক্যামেরা প্রিভিউয়ের জন্য সুপারিশ করা হয়, তবে প্রিভিউ বাফারগুলি প্রক্রিয়া বা অ্যানিমেট করার প্রয়োজন হয় না। এটি টেক্সচারভিউয়ের তুলনায় বেশি কার্যক্ষম এবং কম রিসোর্স-চাহিদাপূর্ণ।

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

উৎস

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

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

ডিসপ্লে রোটেশন ফোন (প্রাকৃতিক অভিযোজন = প্রতিকৃতি) ল্যাপটপ (প্রাকৃতিক অভিযোজন = ল্যান্ডস্কেপ)
0 বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবি
৯০ বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবি
১৮০ বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবি
২৭০ বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবি

লেআউট

আপনি দেখতে পাচ্ছেন, SurfaceView ইতিমধ্যেই আমাদের জন্য কিছু জটিল বিষয় পরিচালনা করে। কিন্তু এখন আপনাকে ভিউফাইন্ডারের আকার বা স্ক্রিনে আপনার প্রিভিউ কত বড় করতে চান তা বিবেচনা করতে হবে। SurfaceView স্বয়ংক্রিয়ভাবে সোর্স বাফারকে তার মাত্রার সাথে মানানসই করে। আপনাকে নিশ্চিত করতে হবে যে ভিউফাইন্ডারের আকৃতির অনুপাত সোর্সবাফারের অনুপাতের সাথে সমান। উদাহরণস্বরূপ, যদি আপনি একটি পোর্ট্রেট-আকৃতির প্রিভিউকে একটি ল্যান্ডস্কেপ-আকৃতির SurfaceView-এ ফিট করার চেষ্টা করেন, তাহলে আপনি এইরকম কিছু বিকৃত পাবেন:

একটি ল্যান্ডস্কেপ-আকৃতির ভিউফাইন্ডারে একটি প্রতিকৃতি-আকৃতির প্রিভিউ লাগানোর ফলে একটি প্রসারিত বাগড্রয়েড দেখানো ছবির চিত্র

আপনি সাধারণত ভিউফাইন্ডারের আকৃতির অনুপাত (অর্থাৎ, প্রস্থ/উচ্চতা) উৎসের আকৃতির অনুপাতের অনুরূপ চান। যদি আপনি ভিউফাইন্ডারে ছবিটি ক্লিপ করতে না চান - ডিসপ্লে ঠিক করার জন্য কিছু পিক্সেল কেটে ফেলতে চান, তাহলে দুটি ক্ষেত্রে বিবেচনা করতে হবে, যখন aspectRatioActivity aspectRatioSource এর চেয়ে বড় এবং যখন এটি aspectRatioSource এর চেয়ে কম বা সমান।

aspectRatioActivity > aspectRatioSource

আপনি কেসটিকে "বিস্তৃত" অ্যাক্টিভিটি হিসেবে ভাবতে পারেন। নীচে আমরা একটি উদাহরণ বিবেচনা করব যেখানে আপনার একটি 16:9 অ্যাক্টিভিটি এবং একটি 4:3 উৎস রয়েছে।

aspectRatioActivity = 16/9 ≈ 1.78
aspectRatioSource = 4/3 ≈ 1.33

প্রথমে আপনি আপনার ভিউফাইন্ডারটিও 4:3 আকারের করতে চান। তারপর আপনি সোর্স এবং ভিউফাইন্ডারকে কার্যকলাপে এভাবে ফিট করতে চান:

এমন একটি কার্যকলাপের চিত্র যার আকৃতির অনুপাত ভিউফাইন্ডারের আকৃতির অনুপাতের চেয়ে বেশি

এই ক্ষেত্রে, আপনার ভিউফাইন্ডারের উচ্চতা কার্যকলাপের উচ্চতার সাথে মিলিত করা উচিত এবং ভিউফাইন্ডারের আকৃতির অনুপাত উৎসের আকৃতির অনুপাতের সাথে অভিন্ন করা উচিত। ছদ্ম কোডটি নিম্নরূপ:

viewfinderHeight = activityHeight;
viewfinderWidth = activityHeight * aspectRatioSource;
aspectRatioActivity ≤ aspectRatioSource

অন্য ক্ষেত্রে যখন কার্যকলাপটি "সংকীর্ণ" বা "লম্বা" হয়। আমরা পূর্ববর্তী উদাহরণটি পুনরায় ব্যবহার করতে পারি, নিম্নলিখিত উদাহরণটি বাদে আপনি ডিভাইসটিকে 90 ডিগ্রি ঘোরান, যার ফলে কার্যকলাপটি 9:16 এবং উৎসটি 3:4 হয়।

aspectRatioActivity = 9/16 = 0.5625
aspectRatioSource = 3/4 = 0.75

এই ক্ষেত্রে, আপনি সোর্স এবং ভিউফাইন্ডারকে কার্যকলাপের সাথে এভাবে ফিট করতে চান:

এমন একটি কার্যকলাপের চিত্র যার আকৃতির অনুপাত ভিউফাইন্ডারের আকৃতির অনুপাতের চেয়ে কম।

আপনার ভিউফাইন্ডারের প্রস্থকে কার্যকলাপের প্রস্থের সাথে মিলিত করা উচিত (পূর্ববর্তী ক্ষেত্রে উচ্চতার বিপরীতে), এবং ভিউফাইন্ডারের আকৃতির অনুপাতকে উৎসের আকৃতির অনুপাতের সাথে অভিন্ন করা উচিত। ছদ্ম কোড:

viewfinderWidth = activityWidth;
viewfinderHeight = activityWidth / aspectRatioSource;
ক্লিপিং

Camera2 নমুনা থেকে AutoFitSurfaceView.kt (github) SurfaceView কে ওভাররাইড করে এবং উভয় মাত্রার কার্যকলাপের সমান বা "শুধুমাত্র বড়" একটি চিত্র ব্যবহার করে অমিল আকৃতির অনুপাত পরিচালনা করে এবং তারপরে ওভারফ্লো হওয়া সামগ্রী ক্লিপ করে। এটি এমন অ্যাপগুলির জন্য কার্যকর যারা প্রিভিউটি সম্পূর্ণ কার্যকলাপ কভার করতে চান বা চিত্র বিকৃত না করে স্থির মাত্রার একটি দৃশ্য সম্পূর্ণরূপে পূরণ করতে চান।

সাবধানতা

পূর্ববর্তী নমুনাটি স্ক্রিন রিয়েল এস্টেটকে সর্বাধিক করে তোলার চেষ্টা করে, অ্যাক্টিভিটির চেয়ে প্রিভিউকে আরও বড় করে যাতে কোনও স্থান খালি না থাকে। এটি নির্ভর করে যে অতিরিক্ত অংশগুলি ডিফল্টভাবে প্যারেন্ট লেআউট (অথবা ViewGroup) দ্বারা ক্লিপ করা হয়। আচরণটি RelativeLayout এবং LinearLayout এর সাথে সামঞ্জস্যপূর্ণ কিন্তু ConstraintLayout এর সাথে নয়। একটি ConstraintLayout শিশুদের ভিউগুলিকে লেআউটের ভিতরে ফিট করার জন্য আকার পরিবর্তন করতে পারে, যা "সেন্টার-ক্রপ" প্রভাবটি ভেঙে দেবে এবং প্রসারিত প্রিভিউ তৈরি করবে। আপনি এই কমিটটিকে একটি রেফারেন্স হিসাবে উল্লেখ করতে পারেন।

টেক্সচারভিউ

টেক্সচারভিউ ক্যামেরা প্রিভিউয়ের কন্টেন্টের উপর সর্বাধিক নিয়ন্ত্রণ প্রদান করে, তবে এর পারফরম্যান্স খরচও বেশি। ক্যামেরা প্রিভিউ সঠিকভাবে প্রদর্শনের জন্য আরও বেশি পরিশ্রমের প্রয়োজন হয়।

উৎস

TextureView এর নীচে, Android প্ল্যাটফর্মটি ডিভাইসের প্রাকৃতিক ওরিয়েন্টেশনের সাথে মেলে সেন্সর ওরিয়েন্টেশন অনুসারে আউটপুট বাফারগুলিকে ঘোরায়। TextureView সেন্সর ওরিয়েন্টেশন পরিচালনা করলেও, এটি ডিসপ্লে রোটেশন পরিচালনা করে না। এটি আউটপুট বাফারগুলিকে ডিভাইসের প্রাকৃতিক ওরিয়েন্টেশনের সাথে সারিবদ্ধ করে, যার অর্থ আপনাকে নিজেই ডিসপ্লে রোটেশন পরিচালনা করতে হবে।

নিচের টেবিলে এটি দেখানো হয়েছে। চিত্রগুলিকে তাদের সংশ্লিষ্ট ডিসপ্লে ঘূর্ণন অনুসারে ঘোরানোর চেষ্টা করুন, আপনি আসলে SurfaceView তে একই চিত্র পাবেন।

ডিসপ্লে রোটেশন ফোন (প্রাকৃতিক অভিযোজন = প্রতিকৃতি) ল্যাপটপ (প্রাকৃতিক অভিযোজন = ল্যান্ডস্কেপ)
0 বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবি
৯০ বাগড্রয়েডের মাথা ডানদিকে নির্দেশিত একটি প্রতিকৃতি আকৃতির ছবিবাগড্রয়েডের মাথা ডানদিকে নির্দেশিত একটি ভূদৃশ্য আকৃতির ছবি
১৮০ বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবি
২৭০ বাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি ভূদৃশ্য আকৃতির ছবিবাগড্রয়েডের মাথা উপরের দিকে তাক করা একটি প্রতিকৃতি আকৃতির ছবি

লেআউট

TextureView এর ক্ষেত্রে লেআউটটি একটু জটিল। TextureView এর জন্য পূর্বে একটি ট্রান্সফর্মেশন ম্যাট্রিক্স ব্যবহার করার পরামর্শ দেওয়া হয়েছিল, কিন্তু সেই পদ্ধতিটি সমস্ত ডিভাইসের জন্য কাজ করে না। আমরা আপনাকে এখানে বর্ণিত ধাপগুলি অনুসরণ করার পরামর্শ দিচ্ছি।

টেক্সচারভিউতে প্রিভিউ সঠিকভাবে লেআউট করার ৩-পদক্ষেপের প্রক্রিয়া:

  1. টেক্সচারভিউয়ের আকারটি নির্বাচিত প্রিভিউ আকারের অনুরূপ সেট করুন।
  2. সম্ভাব্য প্রসারিত টেক্সচারভিউকে প্রিভিউয়ের মূল মাত্রায় ফিরিয়ে আনুন।
  3. ঘড়ির কাঁটার বিপরীত দিকে displayRotation ব্যবহার করে টেক্সচারভিউ ঘোরান।

ধরুন আপনার একটি ফোন আছে যার ডিসপ্লে ৯০ ডিগ্রি ঘূর্ণন করে।

৯০ ডিগ্রি ডিসপ্লে ঘূর্ণন সহ একটি ফোন এবং একটি বস্তুর চিত্রণ

১. টেক্সচারভিউয়ের আকারটি নির্বাচিত প্রিভিউ আকারের অনুরূপ সেট করুন।

ধরুন আপনি যে প্রিভিউ সাইজটি বেছে নিয়েছেন তা হল previewWidth × previewHeight যেখানে previewWidth > previewHeight (সেন্সর আউটপুট প্রকৃতিগতভাবে ল্যান্ডস্কেপ-আকৃতির)। ক্যাপচার সেশন কনফিগার করার সময়, SurfaceTexture#setDefaultBufferSize(int width, height) কল করে প্রিভিউ সাইজ ( previewWidth × previewHeight ) নির্দিষ্ট করা উচিত।

setDefaultBufferSize কল করার আগে, View#setLayoutParams(android.view.ViewGroup.LayoutParams) ব্যবহার করে TextureView এর আকার `previewWidth × previewHeight` এ সেট করা গুরুত্বপূর্ণ। এর কারণ হল TextureView তার পরিমাপিত প্রস্থ এবং উচ্চতা সহ SurfaceTexture#setDefaultBufferSize(int width, height) কে কল করে। যদি TextureView এর আকার আগে থেকে স্পষ্টভাবে সেট না করা থাকে, তাহলে এটি একটি রেস কন্ডিশন তৈরি করতে পারে। প্রথমে TextureView এর আকার স্পষ্টভাবে সেট করে এটি হ্রাস করা যায়।

এখন TextureView সোর্সের মাত্রার সাথে নাও মিলতে পারে। ফোনের ক্ষেত্রে, সোর্সটি পোর্ট্রেট-আকৃতির, তবুও আপনার সেট করা লেআউটপ্যারামের কারণে TextureView ল্যান্ডস্কেপ-আকৃতির। এর ফলে প্রিভিউ প্রসারিত হবে, যেমনটি এখানে দেখানো হয়েছে:

নির্বাচিত প্রিভিউ আকারের একই আকারের টেক্সচারভিউয়ের ভিতরে ফিট করার জন্য প্রসারিত একটি প্রতিকৃতি আকৃতির প্রিভিউয়ের চিত্র চিত্রণ

২. সম্ভাব্য প্রসারিত টেক্সচারভিউকে প্রিভিউয়ের মূল মাত্রায় ফিরিয়ে আনুন।

প্রসারিত প্রিভিউকে উৎসের মাত্রায় ফিরিয়ে আনতে নিম্নলিখিত বিষয়গুলি বিবেচনা করুন।

উৎসের মাত্রা ( sourceWidth × sourceHeight ) হল:

  • previewHeight × previewWidth , যদি প্রাকৃতিক অভিযোজন পোর্ট্রেট বা বিপরীত-প্রতিকৃতি হয় (সেন্সর অভিযোজন 90 বা 270 ডিগ্রি)
  • previewWidth × previewHeight , যদি প্রাকৃতিক অভিযোজন ল্যান্ডস্কেপ বা বিপরীত-ভূমিকা হয় (সেন্সর অভিযোজন 0 বা 180 ডিগ্রি)

View#setScaleX(float) এবং View#setScaleY(float) ব্যবহার করে স্ট্রেচিং ঠিক করুন।

  • সেটস্কেলএক্স ( sourceWidth / previewWidth )
  • সেটস্কেলওয়াই ( sourceHeight / previewHeight )

ছবির চিত্র যেখানে প্রসারিত প্রিভিউকে তার আসল মাত্রায় ফিরিয়ে আনার পদ্ধতি দেখানো হয়েছে

৩. ঘড়ির কাঁটার বিপরীতে `displayRotation` করে প্রিভিউ ঘোরান।

আগেই উল্লেখ করা হয়েছে, ডিসপ্লে ঘূর্ণনের ক্ষতিপূরণ দিতে আপনার ঘড়ির কাঁটার বিপরীতে displayRotation ব্যবহার করে প্রিভিউ ঘোরানো উচিত।

আপনি View#setRotation(float) ব্যবহার করে এটি করতে পারেন।

  • setRotation( -displayRotation ), কারণ এটি ঘড়ির কাঁটার দিকে ঘূর্ণন করে।

ডিভাইসের ডিসপ্লে ওরিয়েন্টেশনের সাথে মিল রেখে প্রিভিউ ঘোরানোর পদ্ধতি দেখানো ছবির চিত্র

নমুনা
  • Jetpack-এ camerax থেকে PreviewView পূর্বে বর্ণিত TextureView লেআউট পরিচালনা করে। এটি PreviewCorrector দিয়ে রূপান্তর কনফিগার করে।

দ্রষ্টব্য: যদি আপনি পূর্বে আপনার কোডে TextureView-এর জন্য ট্রান্সফর্মেশন ম্যাট্রিক্স ব্যবহার করে থাকেন, তাহলে Chromebook-এর মতো প্রাকৃতিকভাবে তৈরি ডিভাইসে প্রিভিউটি ঠিক নাও দেখাতে পারে। সম্ভবত আপনার ট্রান্সফর্মেশন ম্যাট্রিক্স ভুলভাবে সেন্সর ওরিয়েন্টেশনকে 90 বা 270 ডিগ্রি ধরে নিয়েছে। সমাধানের জন্য আপনি GitHub-এর এই কমিটটি দেখতে পারেন, তবে আমরা আপনাকে এখানে বর্ণিত পদ্ধতিটি ব্যবহার করার জন্য আপনার অ্যাপটি স্থানান্তর করার পরামর্শ দিচ্ছি।