Imagen হলো একটি ছবি তৈরির মডেল। এটি ব্যবহারকারীর প্রোফাইলের জন্য কাস্টম অ্যাভাটার তৈরি করতে অথবা ব্যবহারকারীর সম্পৃক্ততা বাড়ানোর জন্য বিদ্যমান স্ক্রিন ফ্লোতে ব্যক্তিগতকৃত ভিজ্যুয়াল অ্যাসেট যুক্ত করতে ব্যবহার করা যেতে পারে।
আপনি Firebase AI Logic SDK ব্যবহার করে আপনার অ্যান্ড্রয়েড অ্যাপ থেকে Imagen মডেল অ্যাক্সেস করতে পারেন। Imagen মডেলগুলো Firebase AI Logic-এর উভয় API প্রোভাইডার— Gemini Developer API (বেশিরভাগ ডেভেলপারের জন্য প্রস্তাবিত) এবং Vertex AI—উভয়ের মাধ্যমেই পাওয়া যায়।
প্রম্পট দিয়ে পরীক্ষা করুন
আদর্শ প্রম্পট তৈরি করতে প্রায়শই একাধিকবার চেষ্টা করতে হয়। আপনি গুগল এআই স্টুডিও (Google AI Studio) -তে ইমেজ প্রম্পট নিয়ে পরীক্ষা-নিরীক্ষা করতে পারেন, যা প্রম্পট ডিজাইন এবং প্রোটোটাইপিংয়ের জন্য একটি আইডিই (IDE)। আপনার প্রম্পটগুলো কীভাবে আরও উন্নত করা যায়, সে সম্পর্কে পরামর্শের জন্য প্রম্পট এবং ইমেজ অ্যাট্রিবিউট গাইডটি পর্যালোচনা করুন।

একটি ফায়ারবেস প্রজেক্ট সেট আপ করুন এবং আপনার অ্যাপটি সংযুক্ত করুন।
আপনার অ্যান্ড্রয়েড প্রজেক্টে ফায়ারবেস যুক্ত করতে ফায়ারবেস ডকুমেন্টেশনে দেওয়া ধাপগুলো অনুসরণ করুন।
গ্রেডল নির্ভরতা যোগ করুন
আপনার build.gradle ফাইলে নিম্নলিখিত ডিপেন্ডেন্সিগুলো যোগ করুন:
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.10.0"))
// Add the dependency for the Firebase AI Logic library. When using the BoM,
// you don't specify versions in Firebase library dependencies
implementation("com.google.firebase:firebase-ai")
}
একটি ছবি তৈরি করুন
আপনার অ্যান্ড্রয়েড অ্যাপে একটি ছবি তৈরি করতে, প্রথমে একটি ঐচ্ছিক কনফিগারেশন সহ একটি ImagenModel ইনস্ট্যানশিয়েট করুন।
আপনি generationConfig প্যারামিটারটি ব্যবহার করে একটি নেতিবাচক প্রম্পট, ছবির সংখ্যা, আউটপুট ছবির অ্যাস্পেক্ট রেশিও, ছবির ফরম্যাট নির্ধারণ করতে এবং একটি ওয়াটারমার্ক যোগ করতে পারেন। আপনি safetySettings প্যারামিটারটি ব্যবহার করে সুরক্ষা এবং ব্যক্তি ফিল্টারগুলো কনফিগার করতে পারেন।
কোটলিন
val config = ImagenGenerationConfig( numberOfImages = 2, aspectRatio = ImagenAspectRatio.LANDSCAPE_16x9, imageFormat = ImagenImageFormat.jpeg(compressionQuality = 100), addWatermark = false, ) // Initialize the Gemini Developer API backend service // For Vertex AI use Firebase.ai(backend = GenerativeBackend.vertexAI()) val model = Firebase.ai(backend = GenerativeBackend.googleAI()).imagenModel( modelName = "imagen-4.0-generate-001", generationConfig = config, safetySettings = ImagenSafetySettings( safetyFilterLevel = ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE, personFilterLevel = ImagenPersonFilterLevel.BLOCK_ALL ), )
জাভা
ImagenGenerationConfig config = new ImagenGenerationConfig.Builder() .setNumberOfImages(2) .setAspectRatio(ImagenAspectRatio.LANDSCAPE_16x9) .setImageFormat(ImagenImageFormat.jpeg(100)) .setAddWatermark(false) .build(); // For Vertex AI use Firebase.ai(backend = GenerativeBackend.vertexAI()) ImagenModelFutures model = ImagenModelFutures.from( FirebaseAI.getInstance(GenerativeBackend.googleAI()).imagenModel( "imagen-4.0-generate-001", config, new ImagenSafetySettings( ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE, ImagenPersonFilterLevel.BLOCK_ALL)) );
একবার আপনার ImagenModel ইনস্ট্যানশিয়েট হয়ে গেলে, আপনি generateImages কল করে ছবি তৈরি করতে পারেন:
কোটলিন
val imageResponse = model.generateImages( prompt = "A hyper realistic picture of a t-rex with a blue bagpack in a prehistoric forest", ) val image = imageResponse.images.first() val bitmapImage = image.asBitmap()
জাভা
ListenableFuture<ImagenGenerationResponse<ImagenInlineImage>> futureResponse = model.generateImages( "A hyper realistic picture of a t-rex with a blue bagpack in a prehistoric forest"); try { ImagenGenerationResponse<ImagenInlineImage> imageResponse = futureResponse.get(); List<ImagenInlineImage> images = null; if (imageResponse != null) { images = imageResponse.getImages(); } if (images != null && !images.isEmpty()) { ImagenInlineImage image = images.get(0); Bitmap bitmapImage = image.asBitmap(); // Use bitmapImage } } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); }
Imagen দিয়ে ছবি সম্পাদনা করুন
Firebase AI Logic SDK-গুলো Imagen মডেলের মাধ্যমে উন্নত ইমেজ এডিটিং ক্ষমতা প্রদান করে, যা আপনাকে নিম্নলিখিত কাজগুলো করতে দেয়:
- মাস্ক ব্যবহার করে ছবি সম্পাদনা করুন , যার মধ্যে বিভিন্ন কাজ অন্তর্ভুক্ত রয়েছে, যেমন—অবজেক্ট যোগ করা বা সরানো, ছবির বিষয়বস্তুকে তার মূল সীমার বাইরে প্রসারিত করা এবং ব্যাকগ্রাউন্ড পরিবর্তন করা।
- নির্দিষ্ট স্টাইল (প্যাটার্ন, টেক্সচার বা আর্টিস্ট স্টাইল) প্রয়োগ করে, বিভিন্ন বিষয়ের (যেমন পণ্য, মানুষ বা প্রাণী) উপর আলোকপাত করে, অথবা বিভিন্ন কন্ট্রোল (যেমন হাতে আঁকা স্কেচ, ক্যানি এজ ইমেজ বা ফেস মেশ) অনুসরণ করে ছবিগুলোকে নিজের মতো করে সাজিয়ে নিন।
মডেল প্রারম্ভিকীকরণ
Imagen সম্পাদনা বৈশিষ্ট্যগুলি ব্যবহার করতে, এমন একটি Imagen মডেল নির্দিষ্ট করুন যা চিত্র সম্পাদনা সমর্থন করে, যেমন imagen-3.0-capability-001 :
val imagenModel = Firebase.ai(backend = GenerativeBackend.vertexAI()) .imagenModel("imagen-3.0-capability-001")
মাস্ক-ভিত্তিক সম্পাদনা
Imagen-এর মাস্ক-ভিত্তিক সম্পাদনা মডেলের জন্য নির্দিষ্ট এলাকা নির্ধারণ করে ছবিতে পরিবর্তন আনার সুযোগ দেয়। এই সক্ষমতা মাস্ক তৈরি ও প্রয়োগ করা, অবজেক্ট যোগ বা অপসারণ করা এবং মূল সীমার বাইরে ছবির বিষয়বস্তু প্রসারিত করাসহ বিভিন্ন ধরনের কাজ করতে সাহায্য করে।
একটি মুখোশ তৈরি করুন
মাস্ক-ভিত্তিক সম্পাদনা, যেমন অবজেক্ট যোগ করা বা অপসারণ করার জন্য, আপনাকে মডেলের যে অংশটি সম্পাদনা করতে হবে, অর্থাৎ মাস্ক , তা নির্ধারণ করতে হবে।
একটি মাস্ক তৈরি করতে, আপনি একটি ক্লাস আইডি পাস করে ImagenBackgroundMask() বা ImagenSemanticMask() ব্যবহার করতে পারেন।
আপনি একটি মাস্ক বিটম্যাপ তৈরি করে এবং সেটিকে ImagenRawMask এ রূপান্তর করে স্ক্রিনে ম্যানুয়ালিও মাস্কটি আঁকতে পারেন। detectDragGestures এবং Canvas ব্যবহার করে, আপনি আপনার অ্যাপে Jetpack Compose-এর মাধ্যমে নিম্নলিখিতভাবে একটি মাস্ক-অঙ্কন ইউজার ইন্টারফেস বাস্তবায়ন করতে পারেন:
//import androidx.compose.ui.graphics.Color as ComposeColor @Composable fun ImagenEditingMaskEditor( sourceBitmap: Bitmap, onMaskFinalized: (Bitmap) -> Unit, ) { val paths = remember { mutableStateListOf<Path>() } var currentPath by remember { mutableStateOf<Path?>(null) } var scale by remember { mutableFloatStateOf(1f) } var offsetX by remember { mutableFloatStateOf(0f) } var offsetY by remember { mutableFloatStateOf(0f) } Column( modifier = Modifier.fillMaxSize(), ) { Box( modifier = Modifier .fillMaxWidth() .pointerInput(Unit) { detectDragGestures( onDragStart = { startOffset -> val transformedStart = Offset( (startOffset.x - offsetX) / scale, (startOffset.y - offsetY) / scale, ) currentPath = Path().apply { moveTo(transformedStart.x, transformedStart.y) } }, onDrag = { change, _ -> currentPath?.let { val transformedChange = Offset( (change.position.x - offsetX) / scale, (change.position.y - offsetY) / scale, ) it.lineTo(transformedChange.x, transformedChange.y) currentPath = Path().apply { addPath(it) } } change.consume() }, onDragEnd = { currentPath?.let { paths.add(it) } currentPath = null }, ) }, ) { Image( bitmap = sourceBitmap.asImageBitmap(), contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Fit, ) Canvas(modifier = Modifier.fillMaxSize()) { val canvasWidth = size.width val canvasHeight = size.height val bitmapWidth = sourceBitmap.width.toFloat() val bitmapHeight = sourceBitmap.height.toFloat() scale = min(canvasWidth / bitmapWidth, canvasHeight / bitmapHeight) offsetX = (canvasWidth - bitmapWidth * scale) / 2 offsetY = (canvasHeight - bitmapHeight * scale) / 2 withTransform( { translate(left = offsetX, top = offsetY) scale(scale, scale, pivot = Offset.Zero) }, ) { val strokeWidth = 70f / scale val stroke = Stroke(width = strokeWidth, cap = StrokeCap.Round, join = StrokeJoin.Round) val pathColor = ComposeColor.White.copy(alpha = 0.5f) paths.forEach { path -> drawPath(path = path, color = pathColor, style = stroke) } currentPath?.let { path -> drawPath(path = path, color = pathColor, style = stroke) } } } } Button( onClick = { val maskBitmap = createMaskBitmap(sourceBitmap, paths) onMaskFinalized(maskBitmap) }, ) { Text("Save mask") } } }
এরপর আপনি ক্যানভাসে পাথগুলো এঁকে মাস্ক বিটম্যাপটি তৈরি করতে পারেন:
// import android.graphics.Color as AndroidColor // import android.graphics.Paint private fun createMaskBitmap( sourceBitmap: Bitmap, paths: SnapshotStateList<Path>, ): Bitmap { val maskBitmap = Bitmap.createBitmap(sourceBitmap.width, sourceBitmap.height, Bitmap.Config.ARGB_8888) val canvas = android.graphics.Canvas(maskBitmap) val paint = Paint().apply { color = AndroidColor.RED strokeWidth = 70f style = Paint.Style.STROKE strokeCap = Paint.Cap.ROUND strokeJoin = Paint.Join.ROUND isAntiAlias = true } paths.forEach { path -> canvas.drawPath(path.asAndroidPath(), paint) } return maskBitmap }
নিশ্চিত করুন যে মাস্কটির আকার মূল ছবির সমান। আরও বিস্তারিত তথ্যের জন্য Imagen AI ক্যাটালগের নমুনাগুলো দেখুন।
বস্তু সন্নিবেশ করুন
আপনি বিদ্যমান কোনো ছবির মধ্যে নতুন কোনো অবজেক্ট বা কন্টেন্ট যুক্ত করতে পারেন, যাকে ইনপেইন্টিংও বলা হয়। মডেলটি নতুন কন্টেন্টটি তৈরি করে নির্দিষ্ট মাস্ক করা অংশে যুক্ত করবে।
এটি করার জন্য, editImage() ফাংশনটি ব্যবহার করুন। আপনাকে মূল ছবিটি এবং একটি মাস্ক প্রদান করতে হবে। এবং আপনি যে বিষয়বস্তু সন্নিবেশ করতে চান তার বর্ণনা দিয়ে একটি টেক্সট প্রম্পট। এছাড়াও, একটি ImagenEditingConfig অবজেক্ট পাস করুন এবং নিশ্চিত করুন যে এর editMode প্রপার্টিটি ImagenEditMode.INPAINT_INSERTION এ সেট করা আছে।
suspend fun insertFlowersIntoImage( model: ImagenModel, originalImage: Bitmap, mask: ImagenMaskReference ): ImagenGenerationResponse<ImagenInlineImage> { val prompt = "a vase of flowers" // Pass the original image, a mask, the prompt, and an editing configuration. val editedImage = model.editImage( referenceImages = listOf( ImagenRawImage(originalImage.toImagenInlineImage()), mask, ), prompt = prompt, // Define the editing configuration for inpainting and insertion. config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION) ) return editedImage }
বস্তুগুলো সরান
ইনপেইন্টিং আপনাকে একটি ছবি থেকে অবাঞ্ছিত বস্তু মুছে ফেলতে সাহায্য করে। এটি করার জন্য, editImage ফাংশনটি ব্যবহার করুন। এর জন্য আপনাকে মূল ছবিটি এবং একটি মাস্ক প্রদান করতে হবে। যা আপনি যে অবজেক্টটি সরাতে চান সেটিকে হাইলাইট করে। ঐচ্ছিকভাবে, আপনি অবজেক্টটির বর্ণনা দেওয়ার জন্য একটি টেক্সট প্রম্পট অন্তর্ভুক্ত করতে পারেন, যা মডেলটিকে সঠিক শনাক্তকরণে সহায়তা করতে পারে। এছাড়াও, আপনাকে অবশ্যই ImagenEditingConfig এর মধ্যে editMode ImagenEditMode.INPAINT_REMOVAL এ সেট করতে হবে।
suspend fun removeBallFromImage( model: ImagenModel, originalImage: Bitmap, mask: ImagenMaskReference ): ImagenGenerationResponse<ImagenInlineImage> { // Optional: provide the prompt describing the content to be removed. val prompt = "a ball" // Pass the original image, a mask, the prompt, and an editing configuration. val editedImage = model.editImage( referenceImages = listOf( ImagenRawImage(originalImage.toImagenInlineImage()), mask ), prompt = prompt, // Define the editing configuration for inpainting and removal. config = ImagenEditingConfig(ImagenEditMode.INPAINT_REMOVAL) ) return editedImage }
ছবির বিষয়বস্তু প্রসারিত করুন
আপনি outpaintImage() ফাংশনটি ব্যবহার করে একটি ছবিকে তার মূল সীমার বাইরে প্রসারিত করতে পারেন, যা আউটপেইন্টিং নামে পরিচিত। এই ফাংশনটির জন্য মূল ছবিটি এবং প্রসারিত ছবিটির প্রয়োজনীয় Dimensions ) প্রয়োজন। ঐচ্ছিকভাবে, আপনি প্রসারণের জন্য একটি বর্ণনামূলক প্রম্পট অন্তর্ভুক্ত করতে পারেন এবং নতুন তৈরি হওয়া ছবিটির মধ্যে মূল ছবিটির ImagenImagePlacement নির্দিষ্ট করে দিতে পারেন।
suspend fun expandImage(originalImage: Bitmap, imagenModel: ImagenModel): ImagenGenerationResponse<ImagenInlineImage> { // Optionally describe what should appear in the expanded area. val prompt = "a sprawling sandy beach next to the ocean" val editedImage = imagenModel.outpaintImage( originalImage.toImagenInlineImage(), Dimensions(1024, 1024), prompt = prompt, newPosition = ImagenImagePlacement.LEFT_CENTER ) return editedImage }
পটভূমি প্রতিস্থাপন করুন
আপনি ছবির সম্মুখভাগের বিষয়বস্তু অপরিবর্তিত রেখে এর পটভূমি পরিবর্তন করতে পারেন। এটি করার জন্য, editImage ফাংশনটি ব্যবহার করুন। এক্ষেত্রে মূল ছবিটি, একটি ImagenBackgroundMask অবজেক্ট (যেটিতে নতুন পটভূমির জন্য একটি টেক্সট প্রম্পট থাকবে), এবং একটি ImagenEditingConfig পাস করুন, যার editMode প্রপার্টিটি ImagenEditMode.INPAINT_INSERTION এ সেট করা থাকবে।
suspend fun replaceBackground(model: ImagenModel, originalImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Provide the prompt describing the new background. val prompt = "space background" // Pass the original image, a mask, the prompt, and an editing configuration. val editedImage = model.editImage( referenceImages = listOf( ImagenRawImage(originalImage.toImagenInlineImage()), ImagenBackgroundMask(), ), prompt = prompt, config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION) ) return editedImage }
কাস্টমাইজেশন
আপনি Imagen-এর কাস্টমাইজেশন সুবিধা ব্যবহার করে এমন রেফারেন্স ইমেজের উপর ভিত্তি করে ছবি তৈরি বা সম্পাদনা করতে পারেন, যেগুলোতে কোনো বিষয়, কন্ট্রোল বা স্টাইল নির্দিষ্ট করা থাকে। মডেলকে নির্দেশনা দেওয়ার জন্য এক বা একাধিক রেফারেন্স ইমেজের সাথে একটি টেক্সট প্রম্পট প্রদান করে এটি সম্পন্ন করা হয়।
একটি বিষয়ের উপর ভিত্তি করে কাস্টমাইজ করুন
আপনি একটি রেফারেন্স ছবি থেকে কোনো নির্দিষ্ট বিষয়ের (যেমন, কোনো পণ্য, ব্যক্তি বা প্রাণী) নতুন ছবি তৈরি করতে পারেন। এর জন্য শুধু একটি টেক্সট প্রম্পট এবং বিষয়টির অন্তত একটি রেফারেন্স ছবি প্রদান করুন। উদাহরণস্বরূপ, আপনি আপনার পোষা প্রাণীর একটি ছবি আপলোড করে সম্পূর্ণ ভিন্ন পরিবেশে সেটির একটি নতুন ছবি তৈরি করতে পারেন।
এটি করার জন্য, ImagenSubjectReference ব্যবহার করে সাবজেক্ট রেফারেন্সটি নির্ধারণ করুন এবং তারপর আপনার প্রম্পটের সাথে এটি editImage এ পাস করুন। এছাড়াও, একটি ImagenEditingConfig অন্তর্ভুক্ত করুন যা editSteps এর সংখ্যা নির্দিষ্ট করে; editSteps মান বেশি হলে সাধারণত আরও ভালো মানের ফলাফল পাওয়া যায়।
suspend fun customizeCatImage(model: ImagenModel, referenceCatImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Define the subject reference using the reference image. val subjectReference = ImagenSubjectReference( image = referenceCatImage.toImagenInlineImage(), referenceId = 1, description = "cat", subjectType = ImagenSubjectReferenceType.ANIMAL ) // Provide a prompt that describes the final image. // The "[1]" links the prompt to the subject reference with ID 1. val prompt = "A cat[1] flying through outer space" // Use the editImage API to perform the subject customization. val editedImage = model.editImage( referenceImages = listOf(subjectReference), prompt = prompt, config = ImagenEditingConfig( editSteps = 50 // Number of editing steps, a higher value can improve quality ) ) return editedImage }
একটি নিয়ন্ত্রণের উপর ভিত্তি করে কাস্টমাইজ করুন
এই কৌশলটি একটি কন্ট্রোল রেফারেন্স ইমেজের উপর ভিত্তি করে একটি নতুন ইমেজ তৈরি করে, যেমন হাতে আঁকা স্কেচ ("স্ক্রিবল"), একটি ক্যানি এজ ইমেজ , বা একটি ফেস মেশ। মডেলটি নতুন ইমেজের লেআউট এবং কম্পোজিশনের জন্য কন্ট্রোল ইমেজটিকে একটি কাঠামোগত নির্দেশিকা হিসাবে ব্যবহার করে, অন্যদিকে টেক্সট প্রম্পটটি রঙ এবং টেক্সচারের মতো বিশদ বিবরণ সরবরাহ করে।
ImagenControlReference দিয়ে একটি কন্ট্রোল রেফারেন্স সংজ্ঞায়িত করুন এবং এটিকে একটি প্রম্পট ও editImage ImagenEditingConfig সাথে editSteps সংখ্যার সাথে প্রদান করুন (উচ্চতর মান গুণমান উন্নত করতে পারে):
suspend fun customizeCatImageByControl(model: ImagenModel, referenceImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Define the subject reference using the reference image. val controlReference = ImagenControlReference( image = referenceImage.toImagenInlineImage(), referenceId = 1, type = ImagenControlType.SCRIBBLE, ) val prompt = "A cat flying through outer space arranged like the scribble map[1]" val editedImage = model.editImage( referenceImages = listOf(controlReference), prompt = prompt, config = ImagenEditingConfig( editSteps = 50 ), ) return editedImage }
একটি শৈলীর উপর ভিত্তি করে কাস্টমাইজ করুন
আপনি একটি রেফারেন্স ইমেজ থেকে, যেমন এর প্যাটার্ন, টেক্সচার বা ডিজাইন, একটি নির্দিষ্ট স্টাইলের সাথে মেলানোর জন্য একটি ইমেজ তৈরি বা সম্পাদনা করতে পারেন। মডেলটি প্রয়োজনীয় নান্দনিকতা বোঝার জন্য রেফারেন্স ইমেজটি ব্যবহার করে এবং টেক্সট প্রম্পটে বর্ণিত নতুন ইমেজটিতে তা প্রয়োগ করে। উদাহরণস্বরূপ, আপনি একটি বিখ্যাত চিত্রকর্মের ইমেজ প্রদান করে সেই চিত্রকর্মের স্টাইলে একটি বিড়ালের ইমেজ তৈরি করতে পারেন।
ImagenStyleReference দিয়ে একটি স্টাইল রেফারেন্স সংজ্ঞায়িত করুন এবং একটি প্রম্পট ও ImagenEditingConfig এর সাথে editSteps সংখ্যাসহ এটি editImage এ প্রদান করুন (উচ্চতর মান গুণমান উন্নত করতে পারে):
suspend fun customizeImageByStyle(model: ImagenModel, referenceVanGoghImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Define the style reference using the reference image. val styleReference = ImagenStyleReference( image = referenceVanGoghImage.toImagenInlineImage(), referenceId = 1, description = "Van Gogh style" ) // Provide a prompt that describes the final image. // The "1" links the prompt to the style reference with ID 1. val prompt = "A cat flying through outer space, in the Van Gogh style[1]" // Use the editImage API to perform the style customization. val editedImage = model.editImage( referenceImages = listOf(styleReference), prompt = prompt, config = ImagenEditingConfig( editSteps = 50 // Number of editing steps, a higher value can improve quality ), ) return editedImage }
পরবর্তী পদক্ষেপ
- Firebase ডকুমেন্টেশনে Firebase AI Logic সম্পর্কে আরও জানুন।
- অ্যান্ড্রয়েড এআই স্যাম্পল ক্যাটালগটি অন্বেষণ করুন।