Imagen هو نموذج لإنشاء الصور. ويمكن استخدامها لإنشاء صور رمزية مخصّصة لملفات المستخدمين الشخصية أو لدمج مواد عرض مرئية مخصّصة في مسارات الشاشة الحالية لزيادة تفاعل المستخدمين.
يمكنك الوصول إلى نماذج Imagen من تطبيق Android باستخدام Firebase AI Logic SDK. تتوفّر نماذج Imagen باستخدام كل من مقدّمي خدمات واجهة برمجة التطبيقات في Firebase AI Logic: Gemini Developer API (ننصح به لمعظم المطوّرين) وVertex AI.
تجربة طلبات مختلفة
يتطلّب إنشاء الطلبات المثالية غالبًا عدّة محاولات. يمكنك تجربة طلبات الصور في Google AI Studio، وهي بيئة تطوير مدمجة لتصميم الطلبات وإنشاء النماذج الأولية. للحصول على نصائح حول كيفية تحسين طلباتك، راجِع دليل سمات الطلبات والصور.

إعداد مشروع على Firebase وربط تطبيقك به
اتّبِع الخطوات الواردة في مستندات Firebase من أجل إضافة Firebase إلى مشروع Android.
إضافة تبعية Gradle
أضِف التبعيات التالية إلى ملف build.gradle
:
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.4.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")
}
إنشاء صورة
لإنشاء صورة في تطبيق Android، ابدأ بإنشاء مثيل من
ImagenModel
باستخدام إعداد اختياري.
يمكنك استخدام المَعلمة generationConfig
لتحديد طلب سلبي وعدد الصور ونسبة العرض إلى الارتفاع للصورة الناتجة وتنسيق الصورة وإضافة علامة مائية. يمكنك استخدام المَعلمة safetySettings
لضبط فلاتر السلامة والأشخاص.
Kotlin
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
)
)
Java
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.ai(backend = GenerativeBackend.googleAI()).imagenModel(
"imagen-4.0-generate-001",
config,
ImagenSafetySettings.builder()
.setSafetyFilterLevel(ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE)
.setPersonFilterLevel(ImagenPersonFilterLevel.BLOCK_ALL)
.build())
);
بعد إنشاء مثيل ImagenModel
، يمكنك إنشاء صور من خلال استدعاء generateImages
:
Kotlin
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()
Java
CompletableFuture<GenerateContentResponse> futureResponse =
model.generateContent(
Content.newBuilder()
.addParts(
Part.newBuilder()
.setText("A hyper realistic picture of a t-rex with a blue bagpack in a prehistoric forest")
.build())
.build());
try {
GenerateContentResponse imageResponse = futureResponse.get();
List<GeneratedImage> images =
imageResponse
.getCandidates(0)
.getContent()
.getParts(0)
.getInlineData()
.getImagesList();
if (!images.isEmpty()) {
GeneratedImage image = images.get(0);
Bitmap bitmapImage = image.asBitmap();
// Use bitmapImage
}
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
تعديل الصور باستخدام Imagen
توفّر حِزم تطوير البرامج (SDK) الخاصة بـ "منطق الذكاء الاصطناعي" في Firebase إمكانات متقدّمة لتعديل الصور من خلال نموذج Imagen، ما يتيح لك إجراء ما يلي:
- تعديل الصور استنادًا إلى الأقنعة، ويشمل ذلك إجراءات مثل إدراج العناصر أو إزالتها، وتوسيع محتوى الصورة خارج حدودها الأصلية، وتغيير الخلفيات
- تخصيص الصور من خلال تطبيق أنماط معيّنة (نقوش أو مواد أو أنماط فنية)، أو التركيز على مواضيع مختلفة (مثل المنتجات أو الأشخاص أو الحيوانات)، أو الالتزام بعناصر تحكّم مختلفة (مثل رسم تخطيطي مرسوم باليد أو صورة ذات حواف حادة أو شبكة وجه)
تهيئة النموذج
لاستخدام ميزات التعديل في Imagen، حدِّد نموذج Imagen يتيح تعديل الصور، مثل imgen-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 = createMask(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 = createBitmap(sourceBitmap.width, sourceBitmap.height)
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(
sources = listOf(
ImagenRawImage(originalImage),
mask),
prompt = prompt,
// Define the editing configuration for inpainting and insertion.
config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION)
)
return editedImage
}
إزالة عناصر
تتيح لك ميزة "الرسم الداخلي" إزالة العناصر غير المرغوب فيها من صورة. لإجراء ذلك، استخدِم الدالة editImage
. عليك تقديم الصورة الأصلية وقناع يبرز العنصر الذي تريد إزالته. يمكنك اختياريًا تضمين طلب نصي لوصف العنصر، ما يساعد النموذج في التعرّف عليه بدقة. بالإضافة إلى ذلك، يجب ضبط
editMode
ضمن ImagenEditingConfig
على 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(
sources = listOf(
ImagenRawImage(originalImage),
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 = model.outpaintImage(
ImagenRawImage(originalImage),
Dimension(width, height),
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(
sources = listOf(
ImagenRawImage(originalImage),
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,
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(
references = listOf(subjectReference),
prompt = prompt,
config = ImagenEditingConfig(
editSteps = 50 // Number of editing steps, a higher value can improve quality
)
)
return editedImage
}
التخصيص استنادًا إلى عنصر تحكّم
تنشئ هذه التقنية صورة جديدة استنادًا إلى صورة مرجعية للتحكّم، مثل رسم تخطيطي مرسوم يدويًا ("خربشة") أو صورة حواف Canny أو شبكة وجه. يستخدم النموذج الصورة الضابطة كدليل هيكلي لتصميم الصورة الجديدة وتكوينها، بينما يقدّم الطلب النصي تفاصيل مثل اللون والملمس.
حدِّد مرجعًا للتحكّم باستخدام ImagenControlReference
وقدِّمه إلى
editImage
مع طلب وImagenEditingConfig
يتضمّن عدد
editSteps
(يمكن أن تؤدي القيمة الأعلى إلى تحسين الجودة):
suspend fun customizeCatImageByControl(model: ImagenModel, referenceCatImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> {
// Define the subject reference using the reference image.
val controlReference = ImagenControlReference(
image = referenceImage,
referenceID = 1,
controlType = CONTROL_TYPE_SCRIBBLE
)
val prompt = "A cat flying through outer space arranged like the scribble map[1]"
val editedImage = model.editImage(
references = listOf(controlReference),
prompt = prompt,
config = ImagenEditingConfig(
editSteps = 50
)
)
return editedImage
}
التخصيص استنادًا إلى نمط
يمكنك إنشاء صورة أو تعديلها لتتطابق مع نمط معيّن من صورة مرجعية، مثل النمط أو الملمس أو التصميم. يستخدم النموذج الصورة المرجعية لفهم الجانب الجمالي المطلوب وتطبيقه على الصورة الجديدة الموصوفة في الطلب النصي. على سبيل المثال، يمكنك إنشاء صورة لقطة بأسلوب لوحة شهيرة من خلال تقديم صورة لتلك اللوحة.
حدِّد مرجعًا للأسلوب باستخدام ImagenStyleReference
وقدِّمه إلى
editImage
مع طلب وImagenEditingConfig
مع عدد
editSteps
(يمكن أن تؤدي القيمة الأعلى إلى تحسين الجودة):
suspend fun customizeImageByStyle(model: ImagenModel, referenceVanGoghImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> {
// Define the style reference using the reference image.
val styleReference = ImagenStyleReference(
image = referenceVanGoghImage,
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(
references = listOf(styleReference),
prompt = prompt,
config = ImagenEditingConfig(
editSteps = 50 // Number of editing steps, a higher value can improve quality
)
)
return editedImage
}
الخطوات التالية
- يمكنك الاطّلاع على مزيد من المعلومات حول منطق الذكاء الاصطناعي في Firebase في مستندات Firebase.
- استكشِف دليل نماذج الذكاء الاصطناعي على Android.