با استفاده از Firebase Auth و توابع در اندروید، نقاط دیدنی را به طور ایمن با Cloud Vision شناسایی کنید

به منظور پاسخ یک API گوگل ابر از برنامه شما، شما نیاز به ایجاد یک API REST میانی است که دستگیره مجوز و ارزش های مخفی مانند کلید API محافظت می کند. بعد از آن شما به نوشتن کد در برنامه تلفن همراه خود نیاز به احراز هویت و ارتباط با این سرویس متوسط.

یکی از راه های ایجاد این REST API با استفاده از فایربیس احراز هویت و توابع، که به شما می دهد موفق، دروازه بدون سرور به ابر API های گوگل است که احراز هویت دستگیره و می توان از نرم افزار تلفن همراه خود را با SDK-پیش ساخته شده نامیده می شود.

این راهنما نشان می دهد که چگونه به استفاده از این روش برای پاسخ به ابر چشم انداز API از برنامه شما. این روش اجازه می دهد همه کاربران تصدیق برای دسترسی ابر چشم انداز خدمات از طریق پروژه ابر شما صورتحساب، بنابراین در نظر گرفتن این که آیا این مکانیزم احرازهویت برای مورد استفاده خود را قبل از اقدام کافی است.

قبل از اینکه شروع کنی

پیکربندی پروژه خود را

  1. اگر قبلاً این کار را نکرده‌اید، Firebase را به پروژه Android خود اضافه کنید .
  2. اگر شما در حال حاضر برای پروژه خود را فعال رابط های برنامه کاربردی مبتنی بر ابر، نمی، این کار را در حال حاضر:

    1. را باز صفحه فایربیس ML رابط های برنامه کاربردی از کنسول فایربیس.
    2. اگر شما در حال حاضر به روز رسانی پروژه خود را به طرح قیمت گذاری فروغ نیست، با کلیک ارتقا به انجام این کار. (شما باعث خواهد شد به روز رسانی تنها اگر پروژه شما می باشد در این طرح فروغ نمی شود.)

      فقط پروژه های سطح فروغ می توانید رابط های برنامه کاربردی مبتنی بر ابر، استفاده کنید.

    3. اگر رابط های برنامه کاربردی مبتنی بر ابر، در حال حاضر فعال نیست، کلیک فعال کردن رابط های برنامه کاربردی مبتنی بر ابر .
  3. پیکربندی فایربیس کلید API موجود خود را به دسترسی غیرمجاز به API ابر چشم انداز:
    1. را باز اعتبارنامه صفحه از کنسول ابر.
    2. برای هر کلید API در لیست، باز کردن نمای ویرایش، و در بخش محدودیت های کلیدی، اضافه کردن تمام رابط های برنامه کاربردی در دسترس جز API ابر چشم انداز به لیست.

استقرار تابع callable

بعد، استقرار تابع ابر شما استفاده خواهد کرد به پل برنامه خود را و API ابر چشم انداز. functions-samples مخزن مثال شما می توانید با استفاده از شامل.

به طور پیش فرض، دسترسی به API ابر چشم انداز از طریق این تابع فقط کاربران احراز هویت شده از دسترسی برنامه خود را به API ابر چشم انداز اجازه می دهد. شما می توانید تابع برای نیازهای مختلف تغییر دهید.

برای استقرار تابع:

  1. کلون و یا دانلود توابع نمونه مخزن و تغییر به vision-annotate-image دایرکتوری:
    git clone https://github.com/firebase/functions-samples
    cd vision-annotate-image
    
  2. نصب وابستگی:
    cd functions
    npm install
    cd ..
    
  3. اگر شما فایربیس CLI را نداشته باشند، آن را نصب کنید .
  4. مقداردهی اولیه یک پروژه فایربیس در vision-annotate-image دایرکتوری. وقتی از شما خواسته، پروژه خود را در لیست انتخاب کنید.
    firebase init
  5. استقرار تابع:
    firebase deploy --only functions:annotateImage

اضافه کردن فایربیس تایید به برنامه شما

قابل فراخوانی تابع مستقر بالا هر گونه درخواست از کاربران غیر تصدیق از برنامه خود را رد می کنند. اگر قبلا این کار را نکردهاید، شما نیاز به اضافه فایربیس تایید به برنامه شما.

اضافه کردن وابستگی های لازم برای برنامه های خود را

  • اضافه کردن وابستگیها برای توابع فایربیس و gson آندروید کتابخانه به ماژول خود را (در سطح برنامه) فایل Gradle (معمولا برنامه / build.gradle): L10N
    implementation 'com.google.firebase:firebase-functions:20.1.0'
    implementation 'com.google.code.gson:gson:2.8.6'
    
  • 1. تصویر ورودی آماده

    به منظور پاسخ ابر چشم انداز، تصویر باید به عنوان یک رشته-base64 کد گذاری فرمت شود. برای پردازش یک تصویر از یک URI فایل ذخیره شده:
    1. مطلع تصویر به عنوان یک Bitmap شی:

      Java

      Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);

      Kotlin+KTX

      var bitmap: Bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
    2. در صورت تمایل، در مقیاس پایین تصویر را به صرفه جویی در پهنای باند. را ببینید ابر چشم انداز اندازه تصویر توصیه می شود.

      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+KTX

      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

      // Scale down bitmap size
      bitmap = scaleBitmapDown(bitmap, 640);

      Kotlin+KTX

      // Scale down bitmap size
      bitmap = scaleBitmapDown(bitmap, 640)
    3. تبدیل شی Bitmap را به یک رشته از base64 کد گذاری:

      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);

      Kotlin+KTX

      // 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)
    4. تصویر ارائه شده توسط Bitmap شی باید راست شود، با هیچ چرخش اضافی مورد نیاز است.

    2. فراخوانی تابع فراخوانی به رسمیت شناختن نشانه

    به رسمیت شناختن نشانه در یک تصویر، استناد به عملکرد قابل فراخوانی، عبور از یک درخواست JSON ابر چشم انداز .

    1. اول، مقداردهی اولیه یک نمونه از توابع ابر:

      Java

      private FirebaseFunctions mFunctions;
      // ...
      mFunctions = FirebaseFunctions.getInstance();
      

      Kotlin+KTX

      private lateinit var functions: FirebaseFunctions
      // ...
      functions = Firebase.functions
      
    2. تعریف یک روش برای فراخوانی تابع:

      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()));
                      }
                  });
      }
      

      Kotlin+KTX

      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))
                  }
      }
      
    3. ایجاد یک درخواست JSON با نوع LANDMARK_DETECTION :

      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("LANDMARK_DETECTION"));
      JsonArray features = new JsonArray();
      features.add(feature);
      request.add("features", features);
      

      Kotlin+KTX

      // 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("LANDMARK_DETECTION"))
      val features = JsonArray()
      features.add(feature)
      request.add("features", features)
      
    4. در نهایت، استناد تابع:

      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
                          // ...
                      }
                  }
              });
      

      Kotlin+KTX

      annotateImage(request.toString())
              .addOnCompleteListener { task ->
                  if (!task.isSuccessful) {
                      // Task failed with an exception
                      // ...
                  } else {
                      // Task completed successfully
                      // ...
                  }
              }
      

    3. اطلاعات در مورد نشانه به رسمیت شناخته شده مطلع

    اگر عملیات شناسایی نقطه عطفی موفق، یک پاسخ JSON از BatchAnnotateImagesResponse خواهد شد در نتیجه این کار بازگشت. هر شی در landmarkAnnotations آرایه نشان دهنده یک نقطه عطفی است که در تصویر به رسمیت شناخته شد. برای هر نقطه عطفی، شما می توانید مختصات محدوده آن در تصویر ورودی دریافت کنید، نام نقطه عطفی است، طول و عرض جغرافیایی آن، نهاد ID گراف دانش خود را (در صورت موجود)، و نمره اعتماد به نفس از مسابقه. مثلا:

    Java

    for (JsonElement label : task.getResult().getAsJsonArray().get(0).getAsJsonObject().get("landmarkAnnotations").getAsJsonArray()) {
        JsonObject labelObj = label.getAsJsonObject();
        String landmarkName = labelObj.get("description").getAsString();
        String entityId = labelObj.get("mid").getAsString();
        float score = labelObj.get("score").getAsFloat();
        JsonObject bounds = labelObj.get("boundingPoly").getAsJsonObject();
        // Multiple locations are possible, e.g., the location of the depicted
        // landmark and the location the picture was taken.
        for (JsonElement loc : labelObj.get("locations").getAsJsonArray()) {
            JsonObject latLng = loc.getAsJsonObject().get("latLng").getAsJsonObject();
            double latitude = latLng.get("latitude").getAsDouble();
            double longitude = latLng.get("longitude").getAsDouble();
        }
    }
    

    Kotlin+KTX

    for (label in task.result!!.asJsonArray[0].asJsonObject["landmarkAnnotations"].asJsonArray) {
        val labelObj = label.asJsonObject
        val landmarkName = labelObj["description"]
        val entityId = labelObj["mid"]
        val score = labelObj["score"]
        val bounds = labelObj["boundingPoly"]
        // Multiple locations are possible, e.g., the location of the depicted
        // landmark and the location the picture was taken.
        for(loc in labelObj["locations"].asJsonArray) {
            val latitude = loc.asJsonObject["latLng"].asJsonObject["latitude"]
            val longitude = loc.asJsonObject["latLng"].asJsonObject["longitude"]
        }
    }