ব্যবহারকারীরা আশা করেন যে থার্ড-পার্টি অ্যাপগুলি তাদের ডিভাইসের নেটিভ ক্যামেরার মতো একই হাই ফিডেলিটি সহ ফটো এবং ভিডিও ক্যাপচার করবে, আলোর অবস্থা বা হার্ডওয়্যার টিয়ার যাই হোক না কেন। Android ইকোসিস্টেমের সম্প্রসারণের সাথে সাথে এই ধারাবাহিকতা বজায় রাখার জন্য মূল আর্কিটেকচারাল বিষয়গুলি বিবেচনা করতে হয়। এই সেশনে দেখানো হয়েছে যে কীভাবে শক্তিশালী, পেশাদার ক্যাপচার পাইপলাইন তৈরি করা যায় যা সমস্ত ফর্ম ফ্যাক্টর জুড়ে নির্ভরযোগ্য থাকার পাশাপাশি ডিভাইসের ক্ষমতাকে সর্বাধিক করে তোলে।
আমরা CameraX-এর লেটেস্ট উন্নতি এক্সপ্লোর করব, আপনাকে দেখাব কীভাবে মোশন ফটো এবং অন-ডিভাইস AI এনহ্যান্সমেন্টের মতো অত্যাধুনিক ক্ষমতা Google Play পরিষেবার মাধ্যমে ইন্টিগ্রেট করা যায়, পাশাপাশি Jetpack XR SDK ব্যবহার করে স্পেশিয়াল অভিজ্ঞতাও দেখাব। এছাড়াও, আমরা CameraX স্কিল দেখব, যা আপনার পছন্দের কোডিং এজেন্টকে এই টকের কনসেপ্ট অটোমেটিক প্রয়োগ করতে দেয় এবং আরও অনেক কিছু!
CameraXViewfinder বিভিন্ন ফর্ম ফ্যাক্টর যেমন, ফোল্ডেবল ডিভাইস জুড়ে ক্যামেরা প্রিভিউ অ্যাডাপ্ট করে। CameraX 1.7-এ, এটি জেসচার কন্ট্রোল ও স্ক্রিন ফ্ল্যাশ সংক্রান্ত সহায়তা যোগ করে।ProjectedDeviceContext পাস করলে CameraX সরাসরি স্মার্ট গ্লাস থেকে ছবি ক্যাপচার করতে পারে।ট্রান্সস্ক্রিপ্ট করা
হ্যালো, সবাইকে স্বাগত।
আমাদের সেশনে আপনাকে স্বাগত।
আমি আমান, আর আমার সাথে আছে স্কট।
আজ, আমরা CameraX এবং অন-ডিভাইস ইন্টেলিজেন্সের মাধ্যমে বিভিন্ন ডিভাইসে আপনার ক্যামেরার অভিজ্ঞতা কীভাবে উন্নত করতে পারেন সে সম্পর্কে কথা বলতে পেরে সত্যিই আনন্দিত।
তাহলে, শুরু করা যাক।
আপনি কীভাবে ফোন ব্যবহার করেন তা নিয়ে ভাবুন।
আমরা প্রায়ই ফোনের ক্যামেরা ব্যবহার করে বিভিন্ন মুহূর্ত ক্যাপচার করি এবং প্রিয়জনদের সাথে শেয়ার করি।
স্মার্টফোন ব্যবহারের অভিজ্ঞতায় ক্যামেরা এখন অত্যন্ত গুরুত্বপূর্ণ হয়ে উঠেছে।
আসলে, স্মার্টফোন কেনার সময় প্রায়ই ভালো ক্যামেরা একটি গুরুত্বপূর্ণ ফ্যাক্টর হিসেবে কাজ করে।
আজ আমরা প্রিমিয়াম ক্যামেরা অভিজ্ঞতা তৈরি করার জন্য দুটি বড় থিম কভার করব।
প্রথমে, আমরা কিছু CameraX ফিচার এক্সপ্লোর করব এবং তারপর, আমরা কিছু অন-ডিভাইস মেশিন লার্নিং টেকনিক সম্পর্কে জানব।
CameraX দিয়ে শুরু করা যাক।
Jetpack CameraX, Android-এ ক্যামেরা অভিজ্ঞতাকে আরও উন্নত করে।
CameraX ছাড়াও, আমাদের কাছে Camera1 এবং Camera2 আছে, যা Android প্ল্যাটফর্ম ফ্রেমওয়ার্কের অংশ।
তাহলে, আপনার কোন লাইব্রেরি ব্যবহার করা উচিত?
Camera1 হল Android-এর আসল ক্যামেরা API।
এটি এখন বন্ধ করে দেওয়া হয়েছে, তাই নতুন অ্যাপের ক্ষেত্রে Camera2 বা CameraX ব্যবহার করা উচিত।
Camera2, Camera1-এর জায়গা নিয়েছে।
তাই, জটিল ব্যবহারের ক্ষেত্রে আপনার যদি লো-লেভেল ক্যামেরা কন্ট্রোলের প্রয়োজন হয়, তাহলে Camera2 একটি ভালো বিকল্প।
তবে, এর জন্য ডিভাইস-নির্দিষ্ট কনফিগারেশন আপনাকে নিজেকেই ম্যানেজ করতে হবে।
এবং সবশেষে, Camera2-এর উপর ভিত্তি করে Jetpack CameraX তৈরি করা হয়েছে।
এটি একটি সামঞ্জস্যপূর্ণ API প্রদান করে এবং ডিভাইস-নির্দিষ্ট কনফিগারেশন অটোমেটিক ম্যানেজ করে।
বেশিরভাগ ডেভেলপারদের জন্য এটি সাজেস্ট করা বিকল্প।
আমাদের একটি খুব গুরুত্বপূর্ণ ঘোষণা করতে হবে।
আমরা Camera1 বন্ধ করার পরিকল্পনা করছি এবং আগামী বছর Android 18-এ Play নীতি এনফোর্সমেন্টের মাধ্যমে এটি শুরু হবে।
আপনি এখনও পুরনো Camera1 API ব্যবহার করলে, আপনাকে CameraX বা Camera2-এ মাইগ্রেট করতে হবে।
তাহলে, আপনি কেন CameraX ব্যবহার করবেন?
প্রথমত, এটি Android 7 এবং তার পরবর্তী ভার্সনে কাজ করে, তাই এটি প্রায় ৯৯% অ্যাক্টিভ Android ডিভাইসের সাথে মানানসই।
দ্বিতীয়ত, এটি ব্যবহার করা সহজ এবং প্রিভিউ, ক্যাপচার ও রেকর্ডিংয়ের মতো সাধারণ ব্যবহারের ক্ষেত্রে কম কোড সহ সহজ API প্রদান করে।
তৃতীয়ত, এটি ডিভাইস-নির্দিষ্ট সমস্যা যেমন প্রিভিউ স্ট্রেচিং, যা ফোল্ডেবল এবং ট্যাবলেটে বেশ সাধারণ, তা কমিয়ে ডিভাইস জুড়ে একটি সামঞ্জস্যপূর্ণ অভিজ্ঞতা প্রদান করে।
এবং সবশেষে, এটি নাইট মোড ও পোর্ট্রেটের মতো উন্নত OEM ক্ষমতার প্রয়োগকে সহজ করে তোলে।
এখন, আমি স্কটকে CameraX-এর কিছু ফিচার সম্পর্কে কথা বলার জন্য আমন্ত্রণ জানাতে চাই।
এখন আপনার পালা, স্কট।
ধন্যবাদ, আমান।
হ্যালো, সবাইকে স্বাগত।
আমার নাম স্কট।
আজ আমরা CameraX-এর বিভিন্ন ফিচার নিয়ে আলোচনা করব, যাতে আপনি পেশাদার-গ্রেডের ক্যামেরা অভিজ্ঞতা তৈরি করতে পারেন।
আর প্রথমেই আছে অ্যাডাপ্টিভ ভিউফাইন্ডার।
বিভিন্ন ফর্ম ফ্যাক্টর ও স্ক্রিন সাইজ জুড়ে হ্যান্ডেল প্রিভিউ করার সময় যাতে কোনও সমস্যা না হয়, সেই জন্য এটি ডিজাইন করা হয়েছে।
ব্যবহারকারীদের কাছে এখন ফোল্ডেবল, ফোন, ল্যাপটপ এবং XR ডিভাইস সহ বিভিন্ন ধরনের ডিভাইস রয়েছে।
তাই, নতুন ফর্ম ফ্যাক্টরের সাথে মানানসই ক্যামেরা অভিজ্ঞতা তৈরি করা আগের চেয়ে অনেক বেশি গুরুত্বপূর্ণ।
আর ক্যামেরা প্রিভিউ ঠিক করা খুবই কঠিন, বিশেষ করে ওয়াইডস্ক্রিন ফোল্ডেবল ডিভাইসে।
এইসব ডিভাইসে, আনফোল্ড করা অবস্থায়, এর ইনার ক্যামেরা অনুভূমিকভাবে মাউন্ট করা থাকে, যেখানে এর ব্যাক ক্যামেরা উল্লম্বভাবে মাউন্ট করা থাকে।
তাই, আপনি যদি ধরে নেন যে সব ক্যামেরা সেন্সর উল্লম্বভাবে মাউন্ট করা আছে, তাহলে আপনি একটি স্থানিক অমিল দেখতে পাবেন এবং এর ফলে বিকৃতি বা সাইডওয়েজ দেখা যাবে।
এবং CameraXViewfinder, এটি আপনার জন্য জটিলতা সম্পূর্ণরূপে পরিচালনা করার জন্য ডিজাইন করা হয়েছে, তাই আপনার ক্যামেরা প্রিভিউ সমস্ত ফর্ম ফ্যাক্টর জুড়ে নির্বিঘ্নে কাজ করে তা নিশ্চিত করে।
এবং CameraXViewfinder কম্পোজেবল কীভাবে ব্যবহার করতে হয় তা দেখা যাক।
var surfaceRequest by remember {
mutableStateOf<SurfaceRequest?>(null)
}
LaunchedEffect(...) {
preview.setSurfaceProvider { surfaceRequest = it }
cameraProvider.bindToLifecycle(..., preview)
}
surfaceRequest?.let { request ->
CameraXViewfinder(
surfaceRequest = request,
contentScale = ContentScale.Fit
)
}প্রথমে, সারফেস অনুরোধ হোল্ড করার জন্য আপনি surfaceRequest কন্টেন্ট ভেরিয়েবল ঘোষণা করেন।
দুঃখিত।
আর দ্বিতীয়ত, দ্বিতীয়ত, LaunchedEffect-এ, আপনি সারফেস প্রোভাইডার সেট করেন যাতে সারফেস রিকোয়েস্ট অবজেক্ট ক্যাচ করা যায়।
তারপর, আপনি লাইফসাইকেলে বাইন্ড করেন এবং ক্যামেরা চালু করেন।
এবং অবশেষে, যখনই কোনও বৈধ সারফেস অনুরোধের সাথে স্টেট আপডেট হয় এবং রিকম্পোজিশন ট্রিগার করে, আপনি সরাসরি CameraXViewfinder-এ অনুরোধ সেট করেন।
এবং এখানে, আপনার পছন্দ অনুযায়ী, contentScale ফিট বা ক্রপ করার জন্য সেট করতে পারবেন।
আর এই পর্যন্তই, আপনি একদম রেডি।
CameraX 1.7-এ, আমরা CameraXViewfinder-এ বেশ কিছু নতুন ফিচার যোগ করেছি।
এর মধ্যে ফোকাস করার জন্য ট্যাপ করা বা জুম করার জন্য পিঞ্চ করার মতো নতুন জেসচার অন্তর্ভুক্ত।
এছাড়াও, এটি স্ক্রিন ফ্ল্যাশ সাপোর্ট করে, যা আপনাকে সেলফি উজ্জ্বল করতে স্ক্রিন ব্যবহার করতে দেয়।
এই ফিচার প্রয়োগ করা সহজ।
CameraXViewfinder(
surfaceRequest = viewModel.surfaceRequest,
contentScale = ContentScale.Fit,
isTapToFocusEnabled = true,
isPinchToZoomEnabled = true,
onScreenFlashReady =
{
imageCapture.screenFlash = it
imageCapture.flashMode = FLASH_MODE_SCREEN
}
)আপনি শুধু 'ফোকাস করতে ট্যাপ করুন' এবং 'জুম করতে পিঞ্চ করুন' বিকল্প চালু করুন।
এবং স্ক্রিন ফ্ল্যাশের জন্য, আপনি onScreenFlashReady কলব্যাক থেকে স্ক্রিন ফ্ল্যাশ ইনস্ট্যান্স পাবেন এবং তারপরে ImageCapture-এ পাস করবেন এবং ফ্ল্যাশ মোড FLASH_MODE_SCREEN-এ সেট করবেন।
আর এইটুকুই।
আমরা দেখেছি যে CameraX কীভাবে ক্যামেরা প্রিভিউ চালু করে যা সমস্ত ফর্ম ফ্যাক্টর জুড়ে নির্বিঘ্নে কাজ করে।
এখন Android XR-এ ক্যামেরা ক্যাপচারের মাধ্যমে আরও এক ধাপ এগিয়ে যাওয়া যাক।
XR ডিভাইসকে তিনটি বিভাগে ভাগ করা যায়: প্রথমত, XR হেডসেট।
এগুলি হল সম্পূর্ণভাবে এনক্লোজড ও ইমারসিভ হেডসেট যা ফিজিক্যাল ওয়ার্ল্ড ক্যাপচার করার জন্য ক্যামেরা ব্যবহার করে, হেডসেটের ভিতরে ডিসপ্লে করে।
এবং দ্বিতীয়ত, তারযুক্ত XR গ্লাস।
আজ আমরা এই বিভাগে কীনোটে XREAL Aura ঘোষণা করেছি।
তাই, আপনি কীনোটে দেখতে পাচ্ছেন যে, এগুলি হল কম্পিউট পাকের সাথে কানেক্ট করা সি-থ্রু চশমা এবং এর মাধ্যমে আপনি বাস্তব জগতের উপর ভার্চুয়াল কন্টেন্ট ওভারলে দেখতে পাবেন।
এবং তৃতীয়টি হল, অডিও ও ডিসপ্লে গ্লাস।
এগুলি হল লাইটওয়েট গ্লাস।
হ্যান্ডস-ফ্রি ও এক ঝলকে দেখার অভিজ্ঞতা প্রদান করতে, তারা অডিও, ক্যামেরা ও ডিসপ্লে একসাথে ব্যবহার করতে পারে।
প্রথম দুটি ক্যাটেগরি, XR হেডসেট ও তারযুক্ত XR গ্লাস, সাধারণ ফোনের মতোই Camera2 ও CameraX-এর সাথে কাজ করে।
তাই আজ আমরা শুধু অডিও এবং ডিসপ্লে গ্লাসের উপর ফোকাস করব।
এইসব স্মার্ট গ্লাসে, অ্যাপগুলি Android ফোনে চলে, স্মার্ট গ্লাসের পরিবর্তে Android ফোন হোস্ট করে, তবে এখানে ফোন ক্যামেরা এবং স্মার্ট গ্লাস ক্যামেরা দুটিরই অ্যাক্সেস রয়েছে।
মূল প্রশ্ন হল, আপনি কোন ক্যামেরার সাথে কথা বলছেন তা কীভাবে জানবেন?
তাই এটি সহজ।
স্ট্যান্ডার্ড Context-এর মাধ্যমে, আপনার CameraX ফোনের ক্যামেরা অ্যাক্সেস করে।
এবং ProjectedDeviceContext-এর মাধ্যমে CameraX স্মার্ট গ্লাসের ক্যামেরা অ্যাক্সেস করে।
তাই বিভিন্ন Context-এর জন্য বিভিন্ন টার্গেট ক্যামেরা থাকবে।
মনে রাখবেন, ক্যামেরা ও স্মার্ট গ্লাসের অনুমতি আলাদা।
ফোন ও চশমার অনুমতি আলাদা, তাই আপনাকে চশমার অনুমতি আলাদাভাবে অনুরোধ করতে হবে।
অন্য বিকল্প হল, আপনি প্রোজেক্ট করা অ্যাক্টিভিটিও ব্যবহার করতে পারেন, যা হোস্ট Android ডিভাইসেও চলে, তবে আপনার UI চশমায় প্রোজেক্ট করা হয়।
আর এখানে নিয়মটি উল্টে যায়।
আপনি স্ট্যান্ডার্ড Context ব্যবহার করলে, স্মার্ট গ্লাসের ক্যামেরা অ্যাক্সেস করতে পারবেন।
আপনি ফোনের ক্যামেরা অ্যাক্সেস করতে চাইলে, আপনাকে HostContext ব্যবহার করতে হবে।
আর কোডটা দেখে নেওয়া যাক, চশমার ক্যামেরা ব্যবহার করে কীভাবে ক্যাপচার করা যায় তা দেখা যাক।
// In a coroutine
val imageCapture = ImageCapture.Builder().build()
ProjectedContext.isProjectedDeviceConnected(activity, coroutineContext)
.collectLatest { isConnected ->
if (isConnected) {
val projectedContext = ProjectedContext.createProjectedDeviceContext(activity)
val cameraConfig = CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig())
.setRepeatingStreamForced(false)
.build()
val cameraProvider = LifecycleCameraProvider.createInstance(projectedContext, cameraConfig)
cameraProvider.bindToLifecycle(activity, DEFAULT_BACK_CAMERA, imageCapture)
}
}
// Shutter button clicked
imageCapture.takePicture(...)প্রথমে, আপনি isProjectedDeviceConnected-কে জিজ্ঞাসা করেন যে স্মার্ট গ্লাস কানেক্ট করা আছে কিনা।
এবং তারপর আপনি projectedContext পেতে createProjectedDeviceContext-এ কল করেন।
দ্বিতীয়ত, এখানে আপনি ProcessCameraProvider-এর পরিবর্তে CameraX শুরু করার জন্য LifecycleCameraProvider ব্যবহার করেন।
সুতরাং ProcessCameraProvider হল একটি সিঙ্গলটন যা আপনি শুরু করার পরে Context af- পরিবর্তন করতে পারবেন না।
তাই LifecycleCameraProvider ব্যবহার করলে আপনি যেকোনও সময় Context পরিবর্তন করতে পারবেন।
এবং এর পরে, আপনাকে CameraX-এ অতিরিক্ত রিপিটিং স্ট্রিম বন্ধ করতে হবে।
এটি প্রয়োজন কারণ আজকের চশমা শুধুমাত্র একটি স্ট্রিম সাপোর্ট করে।
বর্তমানে API ইন্টার্নাল হলেও, আমরা শীঘ্রই এটি সর্বজনীন করব।
আর এইটুকুই।
এখান থেকে স্ট্যান্ডার্ড CameraX, আপনি শুধু ImageCapture বাইন্ড করুন এবং আপনি এখন স্মার্ট গ্লাসের মাধ্যমে ক্যাপচার করছেন।
ঠিক আছে।
এরপর, CameraX কীভাবে আপনাকে একসাথে কাজ করে এমন ফিচার কম্বিনেশন খুঁজে পেতে এবং ডিভাইস থেকে সেরা ফলাফল পেতে সাহায্য করে তা দেখুন।
আধুনিক ক্যামেরা অ্যাপের সংজ্ঞা হল শক্তিশালী ফিচার এবং ব্যবহারকারী আশা করেন যে ক্যামেরা HDR, ৬০ FPS এবং প্রিভিউ স্টেবিলাইজেশনের মতো ফিচার একই সাথে সাপোর্ট করবে।
কিন্তু ডেভেলপার হিসেবে আমরা জানি যে এইসব ফিচার একসাথে একত্রিত করা সবসময় সহজ নয়।
আলাদা আলাদা করে সহায়তা ফিচার কাজ করছে কিনা তা চেক করলে, সেগুলি একসাথে কাজ করবে কিনা তার কোনও গ্যারেন্টি পাওয়া যায় না।
এই অনিশ্চয়তার কারণে ডেভেলপাররা রক্ষণশীল হতে বাধ্য হয়েছেন এবং উপযুক্ত ডিভাইসে ব্যবহারকারী কী কী অভিজ্ঞতা পেতে পারেন তা সীমিত করে দিয়েছেন।
এই সমস্যার সমাধান করতে, আমরা ফিচার গ্রুপ API নিয়ে এসেছি, যা Camera2 ফিচার কম্বিনেশন কোয়েরি ফ্রেমওয়ার্ক দ্বারা পরিচালিত হয়।
এবং এটি ব্যবহার করার দুটি উপায় রয়েছে: প্রথমত, ফিচার কম্বিনেশন কাজ করলে তা চেক করতে এবং চালু করতে requiredFeatureGroup ব্যবহার করুন।
দ্বিতীয়ত, আপনি preferredFeatureGroup-এর মাধ্যমে আপনার ফিচার সংক্রান্ত অগ্রাধিকার প্রদান করতে পারেন এবং তারপর CameraX আপনার জন্য সবচেয়ে ভালো কাজ করে এমন কম্বিনেশন বেছে নেয়।
এবং এখানে উদাহরণ দেওয়া হল।
ডানদিকে, বাঁদিকে, দুঃখিত, কিছু চালু না করে, শুধু একটি সাধারণ ফোন, সাধারণ রেকর্ডিং।
বাঁদিকে, আমরা HDR, ৬০ FPS, প্রিভিউ স্টেবিলাইজেশন একসাথে চালু করি।
এবং আপনি দেখতে পাবেন যে উজ্জ্বল, মসৃণ এবং ঝাঁকুনি-মুক্ত ভিডিওর মাধ্যমে কোয়ালিটি উল্লেখযোগ্যভাবে উন্নত হয়েছে।
আর কোডটা দেখা যাক।
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
SessionConfig(
useCases = listOf(preview, videoCapture),
// HDR_HLG10 > FPS_60 > Preview Stabilization.
preferredFeatureGroup =
listOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION),
)
)তাই এখানে আমরা preferredFeatureGroup ব্যবহার করে আমাদের ফিচার অগ্রাধিকার তালিকা প্রদান করি, যা হল HDR, তারপর ৬০ FPS এবং তারপর প্রিভিউ স্ট্যাবিলাইজেশন।
CameraX কম্বিনেশন চেক করে ডিভাইসে কাজ করে এমন সেরা কম্বিনেশন বেছে নেবে।
CameraX 1.6-এর উপরে, আমরা ফিচার গ্রুপ API-তে 4K রেকর্ডিং এবং ভিডিও স্টেবিলাইজেশন যোগ করছি।
// CameraX 1.6+ supports:
// 4K, video stabilization & Effect
val sessionConfig = SessionConfig(
useCases = listOf(preview, videoCapture),
requiredFeatureGroup =
setOf(UHD_RECORDING, VIDEO_STABILIZATION),
effects = listOf(overlayEffect)
)অনেক প্রিমিয়াম ডিভাইসে 4K ও ভিডিও স্টেবিলাইজেশন একসাথে কাজ করে।
এখন ফিচার গ্রুপ API-এর সাহায্যে, আপনি আত্মবিশ্বাসের সাথে সেগুলি একসাথে চালু করতে পারবেন।
এছাড়াও, আপনি এখন ফিচার গ্রুপ API-এর মাধ্যমে রিয়েল-টাইম এফেক্ট প্রয়োগ করার সুবিধা পাবেন, যা আগে সম্ভব ছিল না।
CameraX-এ কীভাবে খুব ভালো কোয়ালিটির ছবি ক্যাপচার করতে পারবেন সেই সম্পর্কে এবার আলোচনা করা যাক।
CameraX এখন DNG RAW ক্যাপচার করতে পারে।
এটি আপনাকে পেশাদার এডিটিংয়ের জন্য ক্যামেরা সেন্সর থেকে সরাসরি আনপ্রসেসড, আনকমপ্রেসড RAW ছবি অ্যাক্সেস করার সুবিধা দেয়।
এরপরে, আমরা নাইট মোড এক্সটেনশন উন্নত করেছি।
এই এক্সটেনশন ফ্ল্যাশ ব্যবহার না করেই কম আলোতে উজ্জ্বল এবং স্পষ্ট ফটো ক্যাপচার করতে সাহায্য করে।
এছাড়াও, আমরা নতুন নাইট মোড ইন্ডিকেটর API নিয়ে এসেছি।
এটি মনিটর করবে যে বর্তমান পরিবেশ কখন অন্ধকার এবং এটি নাইট মোডের জন্য উপযুক্ত এবং আপনি এটি নাইট মোড ইন্ডিকেটর দেখানোর জন্য ব্যবহার করতে পারেন।
এবং Ultra HDR এখন CameraX এক্সটেনশনে কাজ করে।
এর ফলে নাইট মোডে আরও বেশি ডায়নামিক রেঞ্জ ও ভাইব্র্যান্ট রঙ দেখা যায় এবং আলট্রা HDR সহ নাইট মোড বর্তমানে অনেক সাম্প্রতিক প্রিমিয়াম ডিভাইসে কাজ করে।
আপনি এখানে সাধারণ, নাইট ও আল্ট্রা HDR সহ নাইট মোডের মধ্যে পার্থক্য দেখতে পাবেন।
তাহলে, এটি কীভাবে প্রয়োগ করতে হয় তা দেখা যাক।
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector,
ExtensionSessionConfig(ExtensionMode.NIGHT, extensionsManager))
val imageCapabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
if (imageCapabilities.supportedOutputFormats
.contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR)) {
setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)
}
}.build()
val extensionSessionConfig = ExtensionSessionConfig(
ExtensionMode.NIGHT, extensionsManager, preview, imageCapture
)
cameraProvider.bindToLifecycle(..., extensionSessionConfig)প্রথমে, আপনি নাইট মোডের জন্য একটি ExtensionSessionConfig তৈরি করুন এবং CameraInfo ইনস্ট্যান্স পেতে এটি ব্যবহার করুন।
এবং এর পরে, আপনি ইমেজ ক্যাপচার করার ক্ষমতা পেতে CameraInfo ব্যবহার করেন এবং তারপরে Ultra HDR কাজ করে কিনা তা কোয়েরি করেন।
তারপর আপনি আউটপুট ফর্ম্যাট আল্ট্রা HDR-এ সেট করেন।
এবং সবশেষে, আপনি ব্যবহারের কেস সহ আবার ExtensionSessionConfig তৈরি করেন এবং লাইফসাইকেলে বাইন্ড করেন।
এখন আপনি আল্ট্রা HDR ফটো সহ নাইট মোডে ক্যাপচার করার জন্য প্রস্তুত।
আমরা CameraX-এ মোশন ফটো সংক্রান্ত সহায়তাও নিয়ে এসেছি।
মোশন ফটো, ছবির আশেপাশের সাউন্ড ও মুভমেন্ট ক্যাপচার করে, শুধু স্টিল ছবি নয়, মুহূর্তটি সংরক্ষণ করে।
আমরা বিভিন্ন ফোন, Android ডিভাইস জুড়ে এটিকে স্ট্যান্ডার্ডাইজ করি এবং মোশন ফটো আরও সহজে সাপোর্ট করার ব্যবস্থা করি।
২০২৭ সালের প্রথম ত্রৈমাসিকে CameraX-এ মোশন ফটো ফিচার আসতে চলেছে।
এটি উপলভ্য হলে, ImageCapture.Builder-এ মোশন ফটো মোড সেট করুন এবং এখন আপনি মোশন ফটো ক্যাপচার করা শুরু করতে পারবেন।
val imageCapture = ImageCapture.Builder()
.setMotionPhotoMode(
ImageCapture.MOTION_PHOTO_MODE_ON,
customConfig
)
.build()
cameraProvider.bindToLifecycle(.. imageCapture)
imageCapture.takePicture(...)এরপর, CameraX কীভাবে হাই-স্পিড ভিডিও রেকর্ডিং চালু করে তা এক্সপ্লোর করা যাক।
আধুনিক ক্যামেরা অ্যাপের একটি গুরুত্বপূর্ণ ফিচার হল দ্রুত চলমান অ্যাকশন স্পষ্টভাবে রেকর্ড করা।
এটি বিশেষ করে খেলাধূলার মতো দ্রুত-গতির দৃশ্যের জন্য উপযোগী।
এটি ১২০ বা ২৪০ fps-এ হাই-স্পিড ক্যাপচারের মাধ্যমে করা হয়।
এটি ব্যবহার করার দুটি উপায় আছে।
প্রথমে, একই ফ্রেম রেটে এনকোড করা, তারপর আপনি একটি সত্যিকারের হাই-ফ্রেম-রেট ভিডিও তৈরি করবেন।
অন্য বিকল্পটি হল, ৩০ fps-এ এনকোড করে প্লে করার জন্য প্রস্তুত স্লো-মোশন ভিডিও তৈরি করা।
যেমন, ১২০ fps-এ রেকর্ড করা এক সেকেন্ডের ভিডিও ৩০ fps-এ চালাতে চার সেকেন্ড সময় লাগে।
তাই, এই সময়সীমা স্লো-মোশন এফেক্ট তৈরি করে।
এবং হাই-স্পিড রেকর্ডিং প্রয়োগ করতে, আপনি videoCapture-এর সাথে HighSpeedVideoSessionConfig তৈরি করেন।
val recorder = Recorder.Builder().build()
val videoCapture = VideoCapture.withOutput(recorder)
val frameRateRange = cameraInfo.getSupportedFrameRateRanges(
HighSpeedVideoSessionConfig(videoCapture, preview)).first()
val sessionConfig = HighSpeedVideoSessionConfig(
videoCapture,
preview,
frameRateRange = frameRateRange,
isSlowMotionEnabled = true
)
cameraProvider.bindToLifecycle(
lifecycleOwner, cameraSelector, sessionConfig)
// Start recording slow motion videos.
val recording = recorder.prepareRecording(context, outputOption)
.start(executor, {})তারপর, স্লো-মোশন ভিডিও তৈরি করতে ৩০ fps-এ এনকোড করার জন্য isSlowMotionEnabled-কে true হিসেবে সেট করুন অথবা হাই স্পিড ফ্রেম রেট ভিডিও তৈরি করতে false হিসেবে সেট করুন।
আর স্লো মোশন চালু করা থাকলে, Google Photos অটোমেটিক তা শনাক্ত করে এবং থাম্বনেলে স্লো-মোশন ব্যাজ যোগ করে।
এবং Google Photos-এ এটি কীভাবে কাজ করে তা দেখা যাক।
এখানে স্লো মোশন বিড়ালটিকে একটি নাটকীয় প্রভাব দেয়।
আমার বিড়াল কখনও চায় না যে আমি তাকে স্পর্শ করি।
তাই, দুঃখিত।
সবশেষে, আমাদের কনকারেন্ট API, কনকারেন্ট ক্যামেরা API-তে কিছু উন্নতি দেখা যাক।
কনকারেন্ট API আপনার অ্যাপকে একই সাথে ফ্রন্ট ও রিয়ার ক্যামেরা থেকে স্ট্রিম করতে দেয়।
এই বছর, আমরা কনকারেন্ট ক্যামেরা API-তে কিছু উন্নতি করেছি।
লাইফসাইকেলে বাইন্ড করা এবং ক্যামেরা খোলার পরে আপনি ক্যামেরার কম্পোজিশন ডায়নামিকভাবে আপডেট করতে পারবেন।
তাই, এর মধ্যে অবস্থান, সাইজ ও রেন্ডারিং অর্ডার পরিবর্তন করা অন্তর্ভুক্ত।
এছাড়াও, আপনি গোলাকার কোণ বা সীমানা প্রস্থ এবং সীমানা রঙের মতো স্টাইল যোগ করতে পারেন।
এবং এটি কীভাবে করবেন তা এখানে দেওয়া হল: রাউন্ডিং কর্নার, সীমানা প্রস্থ এবং রঙের মতো স্টাইলিং কনফিগার করতে শুধু CompositionSettings ব্যবহার করুন এবং রেন্ডারিং অর্ডার অ্যাডজাস্ট করতে setZOrder ব্যবহার করুন।
val concurrentCamera =
cameraProvider.bindToLifecycle(list(config1, config2))
// CameraX 1.7 features: rounded corner, border width & color
val pipSettings = CompositionSettings.Builder()
.setOffset(0.2f, 0.2f)
.setScale(0.35f, 0.35f)
.setRoundedCornerRatio(0.15f)
.setBorderWidthRatio(0.02f)
.setBorderColor(Color.WHITE)
.setZOrder(1)
.build()
// CameraX 1.7 features: dynamical composition update
concurrentCamera.setCompositionSettings(
listOf(mainSettings, pipSettings))এবং এর পরে, কম্পোজিশন ডায়নামিকভাবে আপডেট করতে, আপনি শুধু অ্যাক্টিভ কনকারেন্ট ক্যামেরায় setCompositionSettings ইনভোক করুন।
আর এইটুকুই।
আপনি কম্পোজিশন ডায়নামিকভাবে আপডেট করতে পারবেন।
ঠিক আছে।
আমরা এখন সব ফিচার দেখে নিয়েছি।
এখানে একটি গুরুত্বপূর্ণ কল-আউট আছে, তাই আমরা আপনাকে CameraX 1.6 এবং তার উপরের যেকোনও ভার্সনে আপগ্রেড করার জন্য বিশেষভাবে সাজেস্ট করছি।
এগুলি নতুন ফর্ম্যাট, Eclipsa ভিডিও, সাপোর্ট করে এমন আসন্ন ডিভাইসে ক্র্যাশ এড়াতে পারে এবং আপনার CameraX এক্সটেনশন যাতে ফিচার ফিউচার Pixel আপডেটে কাজ করা চালিয়ে যায় তা নিশ্চিত করতে পারে।
এর সাথে, আমরা আমাদের প্রথম সেশন শেষ করছি।
আমরা CameraX ফিচার কভার করেছি যা আপনাকে পেশাদার-গ্রেডের ক্যামেরা অভিজ্ঞতা তৈরি করতে সাহায্য করে এবং এখন আমি আমানকে অন-ডিভাইস AI-এর পরবর্তী সেশন কভার করার জন্য আমন্ত্রণ জানাতে চাই।
ধন্যবাদ, স্কট, CameraX ফিচার সম্পর্কে আমাদের বিস্তারিত জানানোর জন্য।
এখন, আসুন দেখে নেওয়া যাক, কীভাবে আপনি অন-ডিভাইস মেশিন লার্নিং ব্যবহার করে ইন্টেলিজেন্ট ক্যামেরা অভিজ্ঞতা তৈরি করতে পারেন।
অন-ডিভাইস মেশিন লার্নিং দুটি প্রধান ক্ষেত্র জুড়ে ক্যামেরার ব্যবহারের ক্ষেত্রে বিস্তৃত পরিসরকে সক্ষম করে।
প্রথমটি হল প্রি-ক্যাপচার।
এখানে, অবজেক্ট ডিটেকশনের মতো কাজ করার জন্য আপনি রিয়েল টাইমে আপনার ক্যামেরা প্রিভিউ বিশ্লেষণ করতে পারেন অথবা আপনি প্রিভিউ নিজেই উন্নত করতে পারেন।
দ্বিতীয়টি হল ক্যাপচার করার পরে।
আপনি ছবি ক্যাপচার করার পরে, এটির কোয়ালিটি উন্নত করতে পারবেন অথবা ছবির জন্য বিবরণ জেনারেট করার মতো কাজ করতে পারবেন।
এখন, আপনার ক্যামেরা অ্যাপের জন্য আমাদের কাছে থাকা কিছু অন-ডিভাইস মেশিন লার্নিং সমাধান সম্পর্কে জেনে নেওয়া যাক।
প্রথম অন-ডিভাইস ML লাইব্রেরি যার ব্যাপারে আমরা কথা বলতে চলেছি সেটি হল ML Kit।
ML Kit মূলত ভিশন ও ন্যাচারাল ল্যাঙ্গুয়েজ ডোমেনে সাধারণ সমস্যা সমাধানের জন্য তৈরি করা হয়েছে, যেমন টেক্সট শনাক্তকরণ, ফেস ডিটেকশন ও ভাষা অনুবাদ।
গত বছর, আমরা ML Kit চালু করেছি।
ML Kit Vision API-এর কিছু উদাহরণ এখানে দেওয়া হল, যেমন ফেস মেশ ডিটেকশন, সাবজেক্ট সেগমেন্টেশন ও রিয়েল-টাইম অবজেক্ট ডিটেকশন।
হ্যাঁ।
গত বছর আমরা GenAI API নিয়ে এসেছি।
এইসব API, Gemini Nano-র ক্ষমতাকে কাজে লাগিয়ে টেক্সট সারসংক্ষেপ, ছবির বিবরণ এবং আরও অনেক কিছু করার ক্ষমতা প্রদান করে।
Prompt API ব্যবহার করে ছবির বিবরণের একটি উদাহরণ এখানে দেওয়া হল।
আমরা টেক্সট প্রম্পটের সাথে ইমেজ বিটম্যাপ মডেলের কাছে পাঠাই এবং ফলাফলের বিবরণে লেখা থাকে যে ক্যাকটাসের মতো ডিজাইন করা একটি ছোট সবুজ Android রোবট কালো সারফেসের উপর বসে আছে।
এবং এই সব কিছুই ডিভাইসে ঘটে।
দারুণ, তাই না?
Adobe Photoshop তাদের অ্যাপে ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে Prompt API ব্যবহার করছে।
অ্যাসেট এডিট করার সময়, ব্যবহারকারীদের প্রায়ই Photoshop অ্যাপে একাধিক লেয়ার ম্যানেজ করতে হয়।
Prompt API ব্যবহার করে, অ্যাপটি এখন অসংগঠিত লেয়ারের নাম অটোমেটিক পরিবর্তন করতে পারে।
এছাড়াও, অ্যাপটি ছবির জন্য ক্যাপশন এবং হ্যাশট্যাগ তৈরি করতে Prompt API ব্যবহার করে, যা সোশ্যাল মিডিয়ায় শেয়ার করার জন্য খুবই উপযোগী।
Prompt API ব্যবহার করে ছবির বিবরণের জন্য কোডটি দেখা যাক।
// 1. Initialize the on-device GenerativeModel client
val generativeModel = Generation.getClient()
// 2. Check whether Gemini Nano is available on the device
val status = generativeModel.checkStatus()
when (status) {
FeatureStatus.UNAVAILABLE -> {}
FeatureStatus.DOWNLOADABLE -> {}
FeatureStatus.DOWNLOADING -> {}
FeatureStatus.AVAILABLE -> {}
}প্রথমে, আপনার একটি generativeModel ক্লায়েন্ট অবজেক্ট প্রয়োজন, তারপর আপনার ডিভাইসে Gemini Nano উপলভ্য বা ডাউনলোড করা যাবে কিনা তা চেক করুন।
এরপর, আপনার ছবি ও টেক্সট প্রম্পট একত্রিত করে কন্টেন্ট সংক্রান্ত অনুরোধ তৈরি করে এবং অবশেষে Gemini Nano-তে ইনফারেন্স রান করতে এবং আপনার ছবির বিবরণ পেতে generateContent কলে এই অনুরোধ সরবরাহ করে।
// 3. Build a multimodal request with the image and text prompt
val request = generateContentRequest(
ImagePart(bitmap),
TextPart("Describe this image in detail.")
) {}
// 4. Run inference on-device and get the description
val response = generativeModel.generateContent(request)
val description = response.candidates.first().textহ্যাঁ, আমাদের কাছে পরবর্তী অন-ডিভাইস ML লাইব্রেরি হল MediaPipe।
MediaPipe আপনার অ্যাপ্লিকেশনের জন্য বিভিন্ন ধরনের মেশিন লার্নিং সলিউশন অফার করে।
ফেস ডিটেকশন, অবজেক্ট ডিটেকশন, ইমেজ সেগমেন্টেশন এবং আরও অনেক কিছুর মতো বিভিন্ন স্যাম্পেল ব্যবহার করে দেখতে আপনি দ্রুত MediaPipe ওয়েবসাইট দেখতে পারেন।
এইসব ব্যবহারের ক্ষেত্রে ML Kit-এর মতোই সাউন্ড ব্যবহার করা হয়, তাহলে আপনি কোন লাইব্রেরি ব্যবহার করবেন?
MediaPipe এবং ML Kit একই ধরনের সমস্যার সমাধান করলেও, কিছু মূল পার্থক্য রয়েছে।
প্রথমটি হল প্ল্যাটফর্ম সহায়তা।
MediaPipe, Android, iOS, ওয়েব ও Python জুড়ে কাজ করে, যেখানে ML Kit শুধুমাত্র Android ও iOS-এর উপর ফোকাস করে।
এরপর, MediaPipe মডেল কাস্টমাইজেশনের সুবিধা অফার করে, যেখানে ML Kit ব্যবহারের জন্য প্রস্তুত API প্রদান করে।
এবং সবশেষে, MediaPipe ওপেন সোর্স হলেও, ML Kit হল একটি Google SDK।
MediaPipe Vision API ব্যবহার করে জেসচার শনাক্তকরণের একটি উদাহরণ এখানে দেওয়া হল।
এই API ক্যামেরা ইনপুট থেকে রিয়েল-টাইমে হাতের জেসচার শনাক্ত করে।
যেমন, ফোন থেকে দূরে দাঁড়িয়ে হাতের সাধারণ জেসচার ব্যবহার করে ক্যামেরা রেকর্ডিং শুরু বা বন্ধ করার জন্য এটি ব্যবহার করা যেতে পারে।
কোডটি দেখা যাক।
তাই প্রথমে, আপনাকে মডেল পাথ, লাইভ স্ট্রিমিং মোড এবং একটি ফলাফল লিসেনার প্রদান করে GestureRecognizerOptions অবজেক্ট তৈরি করতে হবে।
// 1. Build GestureRecognizerOptions
val options = GestureRecognizerOptions.builder().setBaseOptions(
BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK).build())
.setRunningMode(RunningMode.LIVE_STREAM)
.setResultListener { result, image -> /* Handle detected gesture */ }
.build()
// 2. Create the GestureRecognizer
val gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
// 3. Convert CameraX ImageProxy to MediaPipe MPImage
val bitmap = rotateBitmap(imageProxy.toBitmap(),
imageProxy.imageInfo.rotationDegrees)
val mpImage = BitmapImageBuilder(bitmap).build()
// 4. Run gesture recognition on the image
gestureRecognizer.recognizeAsync(mpImage, frameTime)তারপর বিকল্প থেকে একটি জেসচার রিকগনাইজার অবজেক্ট তৈরি করুন।
এরপর, CameraX ImageProxy পান এবং এটিকে বিটম্যাপে কনভার্ট করুন এবং বিটম্যাপ ব্যবহার করে MediaPipe mpImage অবজেক্ট তৈরি করুন।
অবশেষে, রিয়েল-টাইমে জেসচার শনাক্ত করতে আপনাকে recognizeAsync কলে MediaPipe mpImage অবজেক্ট দিতে হবে।
এর পরে, Google Play পরিষেবা API-এর মাধ্যমে অন-ডিভাইস ছবি ও ভিডিও এনহ্যান্স করার সুবিধা উপলভ্য আছে।
এই মডেলটি বেশিরভাগ প্রিমিয়াম ডিভাইসে টোনম্যাপিং, ডিব্লারিং এবং সুপার রেজোলিউশনের মতো ক্ষমতা প্রদান করে।
এই মডেল ব্যবহার করে টোন ম্যাপ করা এবং আপস্কেল করা ছবির একটি উদাহরণ এখানে দেওয়া হল।
আপনি উন্নত করা ছবিতে আকাশ ও সমুদ্রের আরও গাঢ় রঙ এবং উন্নত শার্পনেস স্পষ্টভাবে দেখতে পাবেন।
ইমেজ উন্নত করার কোডটি দেখে নেওয়া যাক।
// Step 1: Verify device support & install module
val enhancementClient = Enhancement.getClient(context)
suspend fun prepare(): Boolean {
if (!enhancementClient.isDeviceSupported().await()) return false
if (!enhancementClient.isModuleInstalled().await()) {
check(enhancementClient.installModule().await()) {
"Enhancement module install failed"
}
}
return true
}প্রথমে, আপনাকে কোয়েরি করতে হবে যে অন্তর্নিহিত ডিভাইস এটি সাপোর্ট করে কিনা এবং প্রয়োজন হলে, আপনার ডিভাইসে এনহ্যান্সমেন্ট মডিউল ইনস্টল করতে হবে।
এরপর, বিটম্যাপ এবং আপনি যে এনহ্যান্সমেন্ট বেছে নিতে চান তা উল্লেখ করে EnhancementOptions অবজেক্ট তৈরি করুন।
// Step 2: Select Enhancement options & create session
val options = EnhancementOptions(
width = bitmap.width,
height = bitmap.height,
enhancementMode = EnhancementMode.BITMAP,
isTonemappingEnabled = true,
isDeblurAndDenoisePhotoEnabled = true,
isDeblurAndDenoiseVideoEnabled = false,
isUpscalePhotoEnabled = false,
isUpscaleVideoEnabled = false
)
val enhancementSession = enhancementClient
.createSessionAsync(options, enhancementExecutor)এরপর, Google Play পরিষেবা API-এর মাধ্যমে ক্লায়েন্ট সেশন তৈরি করুন, তারপর আপনার ফলাফল বিটম্যাপ ম্যানেজ করার জন্য কলব্যাক নির্ধারণ করুন এবং শেষে বিটম্যাপ ও আপনার ছবি উন্নত করার বিকল্প সহ প্রসেস ফাংশন কল করুন।
// Step 3: Process Enhancement
val enhancedBitmap = suspendCancellableCoroutine { continuation ->
val enhancementCallback = object : EnhancementCallback {
override fun onBitmapProcessed(result: Bitmap) {
if (continuation.isActive) continuation.resume(result)
}
override fun onError(statusCode: Int) {
if (continuation.isActive) {
continuation.resumeWithException(
Exception("Bitmap processing failed: $statusCode")
)
}
}
override fun onSurfaceProcessed(timestamp: Long) {}
}
enhancementSession.process(bitmap, options, enhancementCallback)
}আমরা সম্প্রতি Jetpack Media3-তে ভিডিও এনহ্যান্সমেন্ট API ইন্টিগ্রেট করেছি।
ছবি ও ভিডিও এনহ্যান্সমেন্ট API সম্পর্কে আরও জানতে আমাদের মিডিয়া টক চেক করে দেখতে পারেন।
অন-ডিভাইস ML-এর শেষ যে ফিচারটি নিয়ে আমরা আলোচনা করব সেটি হল লো লাইট বুস্ট।
স্মার্টফোন ব্যবহারকারীদের জন্য কম আলোতে ছবি তোলা একটি সাধারণ সমস্যা।
ব্যবহারকারী কম আলোতে ছবি তুলছেন বা ভিডিও কল করছেন, এমন পরিস্থিতি কল্পনা করুন।
লো লাইট বুস্ট রিয়েল-টাইমে আপনার ক্যামেরা প্রিভিউ উজ্জ্বল করে এই সমস্যার সমাধান করে।
লো লাইট বুস্টের দুটি ভ্যারিয়েন্ট আছে: হার্ডওয়্যার ও সফ্টওয়্যার।
হার্ডওয়্যার ভার্সন OEM হার্ডওয়্যার ব্যবহার করে মেশিন লার্নিং ব্যবহার না করেই কম আলোয় তোলা ফ্রেম উন্নত করে।
অন্যদিকে, সফ্টওয়্যার ভার্সন ফ্রেম উন্নত করতে অন-ডিভাইস ML মডেল ব্যবহার করে।
আসুন, আমরা কীভাবে সফ্টওয়্যার লো লাইট বুস্টের সাথে CameraX ইন্টিগ্রেট করতে পারি তা দ্রুত দেখে নিই, যা Google লো লাইট বুস্ট নামেও পরিচিত।
Google Low Light Boost-এর জন্য দুটি মূল সারফেস প্রয়োজন: প্রথমত, র ক্যামেরা ফ্রেমের জন্য আপনার একটি ইনপুট সারফেস এবং উন্নত আউটপুট ফ্রেমের জন্য একটি আউটপুট টার্গেট সারফেস প্রয়োজন।
CameraX-এর সাথে ইন্টিগ্রেট করতে, CameraEffect-এর মধ্যে Google Low Light Boost পাইপলাইন র্যাপ করুন।
CameraX আপনার জন্য সারফেস লাইফসাইকেল ও রাউটিং অটোমেটিক ও নির্বিঘ্নে ম্যানেজ করে।
অবশেষে, আমরা ২০২৬ সালের চতুর্থ ত্রৈমাসিকে CameraX-এ লো লাইট বুস্ট এফেক্ট লঞ্চ করছি।
// Integrates SW Low Light Boost
val lowLightBoostEffect =
LowLightBoostEffect(
CameraEffect.PREVIEW or
CameraEffect.VIDEO_CAPTURE or
CameraEffect.IMAGE_CAPTURE
)
val sessionConfig = SessionConfig(
useCases = listOf(preview, imageCapture),
effects = lowLightBoostEffect
)
cameraProvider.bindToLifecycle(.. sessionConfig)এর মাধ্যমে, আপনি একটি লো লাইট বুস্ট অবজেক্ট তৈরি করতে এবং আপনার সেশন কনফিগারেশনে এটি যোগ করতে পারবেন, তারপর সেশন কনফিগারেশনটি আপনার ক্যামেরা লাইফসাইকেলে বাইন্ড করতে পারবেন এবং এটি শুধু কাজ করে এমন ডিভাইসে কাজ করে।
এর মাধ্যমে আমরা দুটি বিভাগের শেষ প্রান্তে পৌঁছে গেছি।
আজ আমরা কী কী কভার করেছি তার একটি সংক্ষিপ্ত বিবরণ দেখে নেওয়া যাক।
আজ আমরা আলোচনা করেছি যে কীভাবে আপনি CameraX এবং অন-ডিভাইস মেশিন লার্নিংয়ের মাধ্যমে বিভিন্ন ডিভাইসে আপনার ক্যামেরা অভিজ্ঞতা উন্নত করতে পারেন।
CameraXViewfinder-এর মাধ্যমে, প্রথমে আপনি বিভিন্ন ফর্ম ফ্যাক্টরের সাথে মানানসই করার জন্য ক্যামেরা প্রিভিউ চালু করতে পারবেন।
এরপর, আমরা দেখেছি যে CameraX আপনাকে XR ডিভাইসেও ক্যাপচার করার সুবিধা দেয়।
তারপর, ফিচার গ্রুপ API আপনাকে হার্ডওয়্যার ফিচারের সেরা কম্বিনেশন খুঁজে পেতে সাহায্য করে।
আমরা ইমেজ ক্যাপচার আপগ্রেড করার ব্যাপারেও এক্সপ্লোর করেছি এবং স্লো মোশন ভিডিওর জন্য হাই-স্পিড ভিডিও রেকর্ডিং সম্পর্কে জেনেছি।
অবশেষে, আমরা শিখেছি কীভাবে কনকারেন্ট ক্যামেরা প্রিভিউ ডাই-- ডাইনামিকভাবে উন্নত করা যায়।
এরপর, আমরা ইন্টেলিজেন্ট ভিশন অভিজ্ঞতা তৈরি করার জন্য ML Kit এবং MediaPipe-এর মতো কিছু অন-ডিভাইস মেশিন লার্নিং সমাধান দেখেছি।
সবশেষে, আমরা অন-ডিভাইস ইমেজ ও ভিডিও এনহ্যান্সমেন্টের পাশাপাশি রিয়েল-টাইমে আপনার ক্যামেরা প্রিভিউ উজ্জ্বল করার জন্য লো লাইট বুস্ট দেখেছি।
আগে যেমন উল্লেখ করা হয়েছে, আমরা Camera1 বন্ধ করে দেওয়ার পরিকল্পনা করছি, তাই আমরা আপনাকে CameraX-এ মাইগ্রেট করার জন্য বিশেষভাবে উৎসাহিত করছি।
এই মাইগ্রেশনে সাহায্য করার জন্য, আমরা সম্প্রতি CameraX স্কিল লঞ্চ করেছি।
আপনাকে গাইড করার জন্য আমাদের কাছে মাইগ্রেশন গাইড এবং ক্যামেরা স্যাম্পেল রেপোও আছে।
আজকে আমরা যেসব ফিচার নিয়ে আলোচনা করেছি, সেই সম্পর্কে আরও রিসোর্স অ্যাক্সেস করতে এই লিঙ্কে যেতে পারেন।
এতে ডকুমেন্টেশন, ব্লগ, মাইগ্রেশন রিসোর্সের লিঙ্ক অন্তর্ভুক্ত রয়েছে, সব এক জায়গায়।
আমি এক সেকেন্ড সময় নেব, পজ করুন।
ঠিক আছে।
সবাইকে ধন্যবাদ।
আমাদের কথোপকথন এখানেই শেষ।
var surfaceRequest by remember {
mutableStateOf<SurfaceRequest?>(null)
}
LaunchedEffect(...) {
preview.setSurfaceProvider { surfaceRequest = it }
cameraProvider.bindToLifecycle(..., preview)
}
surfaceRequest?.let { request ->
CameraXViewfinder(
surfaceRequest = request,
contentScale = ContentScale.Fit
)
}CameraXViewfinder(
surfaceRequest = viewModel.surfaceRequest,
contentScale = ContentScale.Fit,
isTapToFocusEnabled = true,
isPinchToZoomEnabled = true,
onScreenFlashReady =
{
imageCapture.screenFlash = it
imageCapture.flashMode = FLASH_MODE_SCREEN
}
)// In a coroutine
val imageCapture = ImageCapture.Builder().build()
ProjectedContext.isProjectedDeviceConnected(activity, coroutineContext)
.collectLatest { isConnected ->
if (isConnected) {
val projectedContext = ProjectedContext.createProjectedDeviceContext(activity)
val cameraConfig = CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig())
.setRepeatingStreamForced(false)
.build()
val cameraProvider = LifecycleCameraProvider.createInstance(projectedContext, cameraConfig)
cameraProvider.bindToLifecycle(activity, DEFAULT_BACK_CAMERA, imageCapture)
}
}
// Shutter button clicked
imageCapture.takePicture(...)cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
SessionConfig(
useCases = listOf(preview, videoCapture),
// HDR_HLG10 > FPS_60 > Preview Stabilization.
preferredFeatureGroup =
listOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION),
)
)// CameraX 1.6+ supports:
// 4K, video stabilization & Effect
val sessionConfig = SessionConfig(
useCases = listOf(preview, videoCapture),
requiredFeatureGroup =
setOf(UHD_RECORDING, VIDEO_STABILIZATION),
effects = listOf(overlayEffect)
)val cameraInfo = cameraProvider.getCameraInfo(cameraSelector,
ExtensionSessionConfig(ExtensionMode.NIGHT, extensionsManager))
val imageCapabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
if (imageCapabilities.supportedOutputFormats
.contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR)) {
setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)
}
}.build()
val extensionSessionConfig = ExtensionSessionConfig(
ExtensionMode.NIGHT, extensionsManager, preview, imageCapture
)
cameraProvider.bindToLifecycle(..., extensionSessionConfig)val imageCapture = ImageCapture.Builder()
.setMotionPhotoMode(
ImageCapture.MOTION_PHOTO_MODE_ON,
customConfig
)
.build()
cameraProvider.bindToLifecycle(.. imageCapture)
imageCapture.takePicture(...)val recorder = Recorder.Builder().build()
val videoCapture = VideoCapture.withOutput(recorder)
val frameRateRange = cameraInfo.getSupportedFrameRateRanges(
HighSpeedVideoSessionConfig(videoCapture, preview)).first()
val sessionConfig = HighSpeedVideoSessionConfig(
videoCapture,
preview,
frameRateRange = frameRateRange,
isSlowMotionEnabled = true
)
cameraProvider.bindToLifecycle(
lifecycleOwner, cameraSelector, sessionConfig)
// Start recording slow motion videos.
val recording = recorder.prepareRecording(context, outputOption)
.start(executor, {})val concurrentCamera =
cameraProvider.bindToLifecycle(list(config1, config2))
// CameraX 1.7 features: rounded corner, border width & color
val pipSettings = CompositionSettings.Builder()
.setOffset(0.2f, 0.2f)
.setScale(0.35f, 0.35f)
.setRoundedCornerRatio(0.15f)
.setBorderWidthRatio(0.02f)
.setBorderColor(Color.WHITE)
.setZOrder(1)
.build()
// CameraX 1.7 features: dynamical composition update
concurrentCamera.setCompositionSettings(
listOf(mainSettings, pipSettings))// 1. Initialize the on-device GenerativeModel client
val generativeModel = Generation.getClient()
// 2. Check whether Gemini Nano is available on the device
val status = generativeModel.checkStatus()
when (status) {
FeatureStatus.UNAVAILABLE -> {}
FeatureStatus.DOWNLOADABLE -> {}
FeatureStatus.DOWNLOADING -> {}
FeatureStatus.AVAILABLE -> {}
}// 3. Build a multimodal request with the image and text prompt
val request = generateContentRequest(
ImagePart(bitmap),
TextPart("Describe this image in detail.")
) {}
// 4. Run inference on-device and get the description
val response = generativeModel.generateContent(request)
val description = response.candidates.first().text// 1. Build GestureRecognizerOptions
val options = GestureRecognizerOptions.builder().setBaseOptions(
BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK).build())
.setRunningMode(RunningMode.LIVE_STREAM)
.setResultListener { result, image -> /* Handle detected gesture */ }
.build()
// 2. Create the GestureRecognizer
val gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
// 3. Convert CameraX ImageProxy to MediaPipe MPImage
val bitmap = rotateBitmap(imageProxy.toBitmap(),
imageProxy.imageInfo.rotationDegrees)
val mpImage = BitmapImageBuilder(bitmap).build()
// 4. Run gesture recognition on the image
gestureRecognizer.recognizeAsync(mpImage, frameTime)// Step 1: Verify device support & install module
val enhancementClient = Enhancement.getClient(context)
suspend fun prepare(): Boolean {
if (!enhancementClient.isDeviceSupported().await()) return false
if (!enhancementClient.isModuleInstalled().await()) {
check(enhancementClient.installModule().await()) {
"Enhancement module install failed"
}
}
return true
}// Step 2: Select Enhancement options & create session
val options = EnhancementOptions(
width = bitmap.width,
height = bitmap.height,
enhancementMode = EnhancementMode.BITMAP,
isTonemappingEnabled = true,
isDeblurAndDenoisePhotoEnabled = true,
isDeblurAndDenoiseVideoEnabled = false,
isUpscalePhotoEnabled = false,
isUpscaleVideoEnabled = false
)
val enhancementSession = enhancementClient
.createSessionAsync(options, enhancementExecutor)// Step 3: Process Enhancement
val enhancedBitmap = suspendCancellableCoroutine { continuation ->
val enhancementCallback = object : EnhancementCallback {
override fun onBitmapProcessed(result: Bitmap) {
if (continuation.isActive) continuation.resume(result)
}
override fun onError(statusCode: Int) {
if (continuation.isActive) {
continuation.resumeWithException(
Exception("Bitmap processing failed: $statusCode")
)
}
}
override fun onSurfaceProcessed(timestamp: Long) {}
}
enhancementSession.process(bitmap, options, enhancementCallback)
}// Integrates SW Low Light Boost
val lowLightBoostEffect =
LowLightBoostEffect(
CameraEffect.PREVIEW or
CameraEffect.VIDEO_CAPTURE or
CameraEffect.IMAGE_CAPTURE
)
val sessionConfig = SessionConfig(
useCases = listOf(preview, imageCapture),
effects = lowLightBoostEffect
)
cameraProvider.bindToLifecycle(.. sessionConfig)