Uygulamanızdan bir Google Cloud API'si çağırmak için yetkilendirmeyi işleyen ve API anahtarları gibi gizli değerleri koruyan bir ara REST API oluşturmanız gerekir. Ardından, bu ara hizmetle kimlik doğrulaması yapmak ve iletişim kurmak için mobil uygulamanızda kod yazmanız gerekir.
Bu REST API'yi oluşturmanın bir yolu, Firebase Authentication ve Functions'ı kullanmaktır. Bu sayede, Google Cloud API'lerine kimlik doğrulama işlemlerini gerçekleştiren ve önceden oluşturulmuş SDK'lar ile mobil uygulamanızdan çağrılabilen, yönetilen ve sunucusuz bir ağ geçidi elde edersiniz.
Bu kılavuzda, uygulamanızdan Cloud Vision API'yi çağırmak için bu tekniğin nasıl kullanılacağı gösterilmektedir. Bu yöntem, kimliği doğrulanmış tüm kullanıcıların Cloud projeniz üzerinden Cloud Vision faturalandırılmış hizmetlerine erişmesine olanak tanır. Bu nedenle, devam etmeden önce bu kimlik doğrulama mekanizmasının kullanım alanınız için yeterli olup olmadığını değerlendirin.
Başlamadan önce
Projenizi yapılandırın
- Henüz yapmadıysanız Firebase'i Android projenize ekleyin.
-
Projeniz için bulut tabanlı API'leri henüz etkinleştirmediyseniz şimdi etkinleştirin:
- Firebase konsolunda Firebase MLAPI'ler sayfasını açın.
-
Projenizi henüz kullandıkça öde Blaze fiyatlandırma planına yükseltmediyseniz Yükselt'i tıklayarak yükseltin. (Yalnızca projeniz Blaze fiyatlandırma planında değilse yükseltmeniz istenir.)
Yalnızca Blaze fiyatlandırma planındaki projeler bulut tabanlı API'leri kullanabilir.
- Bulut tabanlı API'ler henüz etkinleştirilmemişse Bulut tabanlı API'leri etkinleştir'i tıklayın.
- Mevcut Firebase API anahtarlarınızı Cloud Vision API'ye erişime izin vermeyecek şekilde yapılandırın:
- Cloud Console'un Kimlik bilgileri sayfasını açın.
- Listedeki her API anahtarı için düzenleme görünümünü açın ve Anahtar Kısıtlamaları bölümünde, Cloud Vision API hariç mevcut tüm API'leri listeye ekleyin.
Çağrılabilir işlevi dağıtma
Ardından, uygulamanız ile Cloud Vision API arasında köprü oluşturmak için kullanacağınız Cloud Functions işlevini dağıtın. functions-samples deposunda kullanabileceğiniz bir örnek bulunmaktadır.
Varsayılan olarak, Cloud Vision API'ye bu işlev üzerinden erişildiğinde yalnızca uygulamanızın kimliği doğrulanmış kullanıcılarının Cloud Vision API'ye erişmesine izin verilir. İşlevi farklı gereksinimlere göre değiştirebilirsiniz.
İşlevi dağıtmak için:
- functions-samples deposunu klonlayın veya indirin ve
Node-1st-gen/vision-annotate-imagedizinine geçin:git clone https://github.com/firebase/functions-samplescd Node-1st-gen/vision-annotate-image - Bağımlılıkları yükleyin:
cd functionsnpm installcd .. - Firebase CLI'nız yoksa yükleyin.
vision-annotate-imagedizininde bir Firebase projesi başlatın. İstendiğinde listeden projenizi seçin.firebase init
- İşlevi dağıtın:
firebase deploy --only functions:annotateImage
Uygulamanıza Firebase Auth'u ekleme
Yukarıda dağıtılan çağrılabilir işlev, uygulamanızın kimliği doğrulanmamış kullanıcılarından gelen tüm istekleri reddeder. Henüz yapmadıysanız uygulamanıza Firebase Auth'u eklemeniz gerekir.
Uygulamanıza gerekli bağımlılıkları ekleme
<project>/<app-module>/build.gradle.kts veya <project>/<app-module>/build.gradle) ekleyin:
implementation("com.google.firebase:firebase-functions:23.0.0") implementation("com.google.code.gson:gson:2.8.6")
Artık resimleri etiketlemeye hazırsınız.
1. Giriş görüntüsünü hazırlama
Cloud Vision'ı çağırabilmek için resmin base64 kodlu dize olarak biçimlendirilmesi gerekir. Kayıtlı bir dosya URI'sindeki resmi işlemek için:- Resmi
Bitmapnesnesi olarak alma:Kotlin
var bitmap: Bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
Java
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
- İsteğe bağlı olarak, bant genişliğinden tasarruf etmek için resmin ölçeğini küçültebilirsiniz.
Cloud Vision için önerilen resim boyutlarına bakın.
Kotlin
private fun scaleBitmapDown(bitmap: Bitmap, maxDimension: Int): Bitmap { val originalWidth = bitmap.width val originalHeight = bitmap.height var resizedWidth = maxDimension var resizedHeight = maxDimension if (originalHeight > originalWidth) { resizedHeight = maxDimension resizedWidth = (resizedHeight * originalWidth.toFloat() / originalHeight.toFloat()).toInt() } else if (originalWidth > originalHeight) { resizedWidth = maxDimension resizedHeight = (resizedWidth * originalHeight.toFloat() / originalWidth.toFloat()).toInt() } else if (originalHeight == originalWidth) { resizedHeight = maxDimension resizedWidth = maxDimension } return Bitmap.createScaledBitmap(bitmap, resizedWidth, resizedHeight, false) }
Java
private Bitmap scaleBitmapDown(Bitmap bitmap, int maxDimension) { int originalWidth = bitmap.getWidth(); int originalHeight = bitmap.getHeight(); int resizedWidth = maxDimension; int resizedHeight = maxDimension; if (originalHeight > originalWidth) { resizedHeight = maxDimension; resizedWidth = (int) (resizedHeight * (float) originalWidth / (float) originalHeight); } else if (originalWidth > originalHeight) { resizedWidth = maxDimension; resizedHeight = (int) (resizedWidth * (float) originalHeight / (float) originalWidth); } else if (originalHeight == originalWidth) { resizedHeight = maxDimension; resizedWidth = maxDimension; } return Bitmap.createScaledBitmap(bitmap, resizedWidth, resizedHeight, false); }
Kotlin
// Scale down bitmap size bitmap = scaleBitmapDown(bitmap, 640)
Java
// Scale down bitmap size bitmap = scaleBitmapDown(bitmap, 640);
- Bitmap nesnesini base64 kodlu bir dizeye dönüştürün:
Kotlin
// Convert bitmap to base64 encoded string val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) val imageBytes: ByteArray = byteArrayOutputStream.toByteArray() val base64encoded = Base64.encodeToString(imageBytes, Base64.NO_WRAP)
Java
// Convert bitmap to base64 encoded string ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); byte[] imageBytes = byteArrayOutputStream.toByteArray(); String base64encoded = Base64.encodeToString(imageBytes, Base64.NO_WRAP);
Bitmap nesnesiyle temsil edilen resim dik olmalı ve ek döndürme gerektirmemelidir.
2. Resmi etiketlemek için çağrılabilir işlevi çağırın.
Bir resimdeki nesneleri etiketlemek için JSON Cloud Vision isteği ileten çağrılabilir işlevi çağırın.Öncelikle bir Cloud Functions işlevi örneğini başlatın:
Kotlin
private lateinit var functions: FirebaseFunctions // ... functions = Firebase.functionsJava
private FirebaseFunctions mFunctions; // ... mFunctions = FirebaseFunctions.getInstance();İşlevi çağırmak için bir yöntem tanımlayın:
Kotlin
private fun annotateImage(requestJson: String): Task<JsonElement> { return functions .getHttpsCallable("annotateImage") .call(requestJson) .continueWith { task -> // This continuation runs on either success or failure, but if the task // has failed then result will throw an Exception which will be // propagated down. val result = task.result?.data JsonParser.parseString(Gson().toJson(result)) } }Java
private Task<JsonElement> annotateImage(String requestJson) { return mFunctions .getHttpsCallable("annotateImage") .call(requestJson) .continueWith(new Continuation<HttpsCallableResult, JsonElement>() { @Override public JsonElement then(@NonNull Task<HttpsCallableResult> task) { // This continuation runs on either success or failure, but if the task // has failed then getResult() will throw an Exception which will be // propagated down. return JsonParser.parseString(new Gson().toJson(task.getResult().getData())); } }); }Type (Tür) değeri
LABEL_DETECTIONolarak ayarlanmış JSON isteğini oluşturun:Kotlin
// Create json request to cloud vision val request = JsonObject() // Add image to request val image = JsonObject() image.add("content", JsonPrimitive(base64encoded)) request.add("image", image) // Add features to the request val feature = JsonObject() feature.add("maxResults", JsonPrimitive(5)) feature.add("type", JsonPrimitive("LABEL_DETECTION")) val features = JsonArray() features.add(feature) request.add("features", features)Java
// Create json request to cloud vision JsonObject request = new JsonObject(); // Add image to request JsonObject image = new JsonObject(); image.add("content", new JsonPrimitive(base64encoded)); request.add("image", image); //Add features to the request JsonObject feature = new JsonObject(); feature.add("maxResults", new JsonPrimitive(5)); feature.add("type", new JsonPrimitive("LABEL_DETECTION")); JsonArray features = new JsonArray(); features.add(feature); request.add("features", features);Son olarak işlevi çağırın:
Kotlin
annotateImage(request.toString()) .addOnCompleteListener { task -> if (!task.isSuccessful) { // Task failed with an exception // ... } else { // Task completed successfully // ... } }Java
annotateImage(request.toString()) .addOnCompleteListener(new OnCompleteListener<JsonElement>() { @Override public void onComplete(@NonNull Task<JsonElement> task) { if (!task.isSuccessful()) { // Task failed with an exception // ... } else { // Task completed successfully // ... } } });
3. Etiketli nesneler hakkında bilgi edinme
Resim etiketleme işlemi başarılı olursa görevin sonucunda BatchAnnotateImagesResponse adlı bir JSON yanıtı döndürülür.labelAnnotations dizisindeki her nesne, resimde etiketlenen bir öğeyi temsil eder. Her etiket için etiketin metin açıklamasını, Bilgi Grafiği varlık kimliğini (varsa) ve eşleşmenin güven puanını alabilirsiniz. Örneğin:
Kotlin
for (label in task.result!!.asJsonArray[0].asJsonObject["labelAnnotations"].asJsonArray) {
val labelObj = label.asJsonObject
val text = labelObj["description"]
val entityId = labelObj["mid"]
val confidence = labelObj["score"]
}
Java
for (JsonElement label : task.getResult().getAsJsonArray().get(0).getAsJsonObject().get("labelAnnotations").getAsJsonArray()) {
JsonObject labelObj = label.getAsJsonObject();
String text = labelObj.get("description").getAsString();
String entityId = labelObj.get("mid").getAsString();
float score = labelObj.get("score").getAsFloat();
}