اذهب إلى المحتوى

السؤال

نشر

قمت بتصميم 3 صفحات في أندرويد ستوديو حيث أن الصفحة الأولى تحوي تصنيف للصورة باستخدام نموذج ML وبعد تصنيفها تظهر في الصفحة الثانية وهناك عدة خيارات منها الانتقال إلى صفحة 3 والذي يحوي Chat-Bot باستخدام gemini  نموذج gemini-2.5-flash للتعرف على الصورة وبناء ردود عليها

لكن المشكلة عند فتح صفحة الشات يحدث تعليق للتطبيق ويظهر السبب في الصورة بسبب الحجم مع أنه عند المحاولة لأول مرة اشتغل ولكن بعدها أصبح لايستجيب كيف أتأكد من السبب وكيف أحلها

أيضًا هل ممكن عمل الشات باستخدام Firebase AI Logic مع أن النموذج يعمل In Local وبعض الوظائف الأخرى تعمل على خدمات Firebase مختلفة

Recommended Posts

  • 0
نشر

ربما حجم الصورة كبير، فالصو الملتقطة بالكاميرا أو المختارة من المعرض، دقتها عالية جداً مثلاً 4000x3000 بكسل، وعند تحميلها في الذاكرة كـ Bitmap، تستهلك مساحة كبيرة.

أو تمرر الصورة كـ Bitmap كامل بين صفحة 2 وصفحة 3 عبر Intent Extras، فتواجه خطأ TransactionTooLargeException.

لذا قبل إرسال الصورة إلى Gemini API، يجب تصغير حجمها وضغطها، فنماذج Gemini لا تحتاج إلى صور بدقة 4K للتعرف عليها، يكفي دقة 720p أو 1080p.

وإليك مثال:

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import java.io.ByteArrayOutputStream

fun resizeAndCompressImage(bitmap: Bitmap, maxDimension: Int = 1024, quality: Int = 80): Bitmap {
    val originalWidth = bitmap.width
    val originalHeight = bitmap.height
    var resizedWidth = originalWidth
    var resizedHeight = originalHeight

    // Resize the image (تصغير الأبعاد)
    if (originalHeight > maxDimension || originalWidth > maxDimension) {
        if (originalWidth > originalHeight) {
            resizedWidth = maxDimension
            resizedHeight = (resizedWidth * originalHeight / originalWidth.toFloat()).toInt()
        } else {
            resizedHeight = maxDimension
            resizedWidth = (resizedHeight * originalWidth / originalHeight.toFloat()).toInt()
        }
    }

    val resizedBitmap = Bitmap.createScaledBitmap(bitmap, resizedWidth, resizedHeight, false)

    // Compress the image (ضغط الجودة)
    val outputStream = ByteArrayOutputStream()
    resizedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
    
    val compressedBytes = outputStream.toByteArray()
    return BitmapFactory.decodeByteArray(compressedBytes, 0, compressedBytes.size)
}

val originalBitmap: Bitmap =  // الصورة الأصلية
val optimizedBitmap = resizeAndCompressImage(originalBitmap)

كذلك يجب أن تتم كل عمليات معالجة الصورة والاتصال بالـ API في thread خلفي لتجنب تجميد واجهة المستخدم، وأفضل طريقة للقيام بذلك في أندرويد هي بواسطة Coroutines

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.ai.client.generativeai.GenerativeModel
import com.google.ai.client.generativeai.type.content
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import android.graphics.Bitmap

class ChatViewModel : ViewModel() {

    private val generativeModel: GenerativeModel = // تهيئة النموذج هنا

    fun analyzeImage(prompt: String, image: Bitmap) {
        viewModelScope.launch {
            try {
                val optimizedImage = withContext(Dispatchers.Default) {
                  
                    resizeAndCompressImage(image, maxDimension = 768, quality = 75)
                }

                val inputContent = content {
                    image(optimizedImage)
                    text(prompt)
                }
                
                val response = generativeModel.generateContent(inputContent)

                withContext(Dispatchers.Main) {
                    _chatResponse.value = response.text 
                }

            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                  
                }
            }
        }
    }
}

ولا تقم بتمرير الـ Bitmap مباشرة، بل تمرير مسار URI للصورة كـ String من صفحة 1 إلى 2 ثم إلى 3، وفي صفحة 3، قم بقراءة الـ Bitmap من الـ URI ثم قم بمعالجته وإرساله.

وبعد التصنيف في صفحة 1، قم بحفظ النسخة المصغرة في ذاكرة التخزين المؤقت للتطبيق  ومرر مسار الملف الجديد إلى الصفحات التالية.

بتاريخ 10 دقائق مضت قال Rol Ian:

أيضًا هل ممكن عمل الشات باستخدام Firebase AI Logic مع أن النموذج يعمل In Local وبعض الوظائف الأخرى تعمل على خدمات Firebase مختلفة

النموذج المحلي سيعمل على جهاز المستخدم للتصنيف الأولي، لكن مهمة الشات مع Gemini تستطيع نقلها إلى الخادم باستخدام Cloud Functions for Firebase والتي هي أساس Firebase AI Extensions و Genkit.

أي في التطبيق سيقوم المستخدم بتصنيف الصورة باستخدام النموذج المحلي، وعند الانتقال لصفحة الشات، ثم يعمل التطبيق على رفع الصورة المُصغّرة إلى Cloud Storage for Firebase.

وعند كتابة المستخدم لسؤال، سيقوم التطبيق بإرساله ورابط الصورة في Cloud Storage إلى Cloud Function.

وفي الخادم Firebase Cloud Function سيتم تفعيل الـ Function عند استدعائها من التطبيق، سواء مكتوبة بـ Node.js وTypeScript أو Python لتستقبل السؤال ورابط الصورة.

ثم تقوم باستدعاء Gemini API من الخادم وذلك أفضل من حيث الأمان، ثم تستقبل الرد من Gemini، ثم إرسال الرد مرة أخرى إلى التطبيق، إما مباشرة كرد على الاستدعاء أو عن طريق كتابته في Firestore أو Realtime Database حيث يستمع التطبيق للتحديثات.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...