每次我尝试调用云函数时,它都会通过异常代码 "NOT_FOUND"
Every time I'm try to call the cloud function and it will through exception code "NOT_FOUND"
描述错误
我正在使用 firebase 新更新服务 https://firebase.google.com/docs/ml/android/recognize-text。我正在尝试从图像中打印文本数据,但异常通过。
.
复制
这是我的科特林代码
package jp.co.camrininfotech.mlText
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.provider.Settings
import android.util.Base64
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.google.android.gms.tasks.Task
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.FirebaseFunctionsException
import com.google.firebase.functions.ktx.functions
import com.google.firebase.ktx.Firebase
import com.google.gson.*
import java.io.ByteArrayOutputStream
import java.io.File
class MainActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var functions: FirebaseFunctions
private var myImageView: ImageView? = null
private var myTextView: TextView? = null
private var WRITE_STORAGE = 100
private var SELECT_PHOTO = 102
private val request = JsonObject()
var photo: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myTextView = findViewById(R.id.textView)
myImageView = findViewById(R.id.imageView)
findViewById<View>(R.id.checkText).setOnClickListener(this)
findViewById<View>(R.id.select_image).setOnClickListener(this)
functions = Firebase.functions
}
override fun onClick(view: View?) {
if (view != null) {
when (view.getId()) {
R.id.checkText -> {
processImage()
}
R.id.select_image -> selectPicture()
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
WRITE_STORAGE ->
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
selectPicture()
} else {
requestPermission(this, requestCode, R.string.permission_request)
}
}
}
private fun requestPermission(activity: Activity, requestCode: Int, msg: Int) {
val alert = AlertDialog.Builder(activity)
alert.setMessage(msg)
alert.setPositiveButton(
android.R.string.ok
) { dialogInterface, i ->
dialogInterface.dismiss()
val permissonIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
permissonIntent.data = Uri.parse("package:" + activity.packageName)
activity.startActivityForResult(permissonIntent, requestCode)
}
alert.setNegativeButton(
android.R.string.cancel
) { dialogInterface, i -> dialogInterface.dismiss() }
alert.setCancelable(false)
alert.show()
}
private fun selectPicture() {
photo = createTempFile(photo)
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent, SELECT_PHOTO)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val dataUri = data!!.data
var bitmap: Bitmap = MediaStore.Images.Media.getBitmap(contentResolver, dataUri)
// Scale down bitmap size
bitmap = scaleBitmapDown(bitmap, 640)
myImageView!!.setImageBitmap(bitmap)
convertIntoBase(bitmap)
}
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)
}
private fun convertIntoBase(bitmap: Bitmap) {
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
val imageBytes: ByteArray = byteArrayOutputStream.toByteArray()
val base64encoded = Base64.encodeToString(imageBytes, Base64.NO_WRAP)
requestJsonToCloud(base64encoded)
}
private fun requestJsonToCloud(base64encoded: String) {
val image = JsonObject()
image.add("content", JsonPrimitive(base64encoded))
request.add("image", image)
val feature = JsonObject()
feature.add("type", JsonPrimitive("TEXT_DETECTION"))
val features = JsonArray()
features.add(feature)
request.add("features", features)
val imageContext = JsonObject()
val languageHints = JsonArray()
languageHints.add("en")
imageContext.add("languageHints", languageHints)
request.add("imageContext", imageContext)
}
private fun processImage() {
annotateImage(request.toString())
.addOnCompleteListener { task ->
if (!task.isSuccessful) {
val e = task.exception
if (e is FirebaseFunctionsException) {
val code = e.code
val details = e.details
Log.w("exception code ", "$code")
Log.w("exception details", "$details")
}
showSnackbar("An error occurred.")
} else {
val annotation =
task.result!!.asJsonArray[0].asJsonObject["fullTextAnnotation"].asJsonObject
System.out.format("%nComplete annotation:")
System.out.format("%n%s", annotation["text"].asString)
}
}
}
private fun showSnackbar(message: String) {
Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_SHORT).show()
}
private fun createTempFile(fileClass: File?): File {
var file = fileClass
val directory =
File(Environment.getExternalStorageDirectory().path + "/jp.co.camrininfotech.mlText")
if (!directory.exists() || !directory.isDirectory) {
directory.mkdirs()
}
if (file == null) {
file = File(directory, "orig.jpg")
}
return file
}
private fun annotateImage(requestJson: String): Task<JsonElement> {
return functions
.getHttpsCallable("annotateImage")
.call(requestJson)
.continueWith { task ->
println("annotateImage result " + task.result.toString())
val result = task.result?.data
JsonParser.parseString(Gson().toJson(result))
}
}
private fun checkPermission(requestCode: Int) {
when (requestCode) {
WRITE_STORAGE -> {
val hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {
selectPicture()
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
requestCode
)
}
}
}
}
}
我正在使用这些依赖项
implementation 'com.google.firebase:firebase-auth-ktx'
implementation platform('com.google.firebase:firebase-bom:28.0.1')
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'com.firebaseui:firebase-ui-auth:7.1.1'
implementation 'com.google.firebase:firebase-functions-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
预期行为
打印图像中的文本
其他上下文
W/exception代码:NOT_FOUNDW/exception详情:空
我找到了这个问题的解决方案。我没有在我的 firebase 云函数中上传 vision-annotate-images。
To deploy the function:
Clone or download the functions-samples repo and change to the vision-annotate-image directory:
git clone https://github.com/firebase/functions-samples
cd vision-annotate-image
Install dependencies:
cd functions
npm install
cd ..
If you don't have the Firebase CLI, install it.
Initialize a Firebase project in the vision-annotate-image directory. When prompted, select your project in the list.
firebase init
Deploy the function:
firebase deploy --only functions:annotateImage
描述错误
我正在使用 firebase 新更新服务 https://firebase.google.com/docs/ml/android/recognize-text。我正在尝试从图像中打印文本数据,但异常通过。
.
复制
这是我的科特林代码
package jp.co.camrininfotech.mlText
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.provider.Settings
import android.util.Base64
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.google.android.gms.tasks.Task
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.FirebaseFunctionsException
import com.google.firebase.functions.ktx.functions
import com.google.firebase.ktx.Firebase
import com.google.gson.*
import java.io.ByteArrayOutputStream
import java.io.File
class MainActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var functions: FirebaseFunctions
private var myImageView: ImageView? = null
private var myTextView: TextView? = null
private var WRITE_STORAGE = 100
private var SELECT_PHOTO = 102
private val request = JsonObject()
var photo: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myTextView = findViewById(R.id.textView)
myImageView = findViewById(R.id.imageView)
findViewById<View>(R.id.checkText).setOnClickListener(this)
findViewById<View>(R.id.select_image).setOnClickListener(this)
functions = Firebase.functions
}
override fun onClick(view: View?) {
if (view != null) {
when (view.getId()) {
R.id.checkText -> {
processImage()
}
R.id.select_image -> selectPicture()
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
WRITE_STORAGE ->
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
selectPicture()
} else {
requestPermission(this, requestCode, R.string.permission_request)
}
}
}
private fun requestPermission(activity: Activity, requestCode: Int, msg: Int) {
val alert = AlertDialog.Builder(activity)
alert.setMessage(msg)
alert.setPositiveButton(
android.R.string.ok
) { dialogInterface, i ->
dialogInterface.dismiss()
val permissonIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
permissonIntent.data = Uri.parse("package:" + activity.packageName)
activity.startActivityForResult(permissonIntent, requestCode)
}
alert.setNegativeButton(
android.R.string.cancel
) { dialogInterface, i -> dialogInterface.dismiss() }
alert.setCancelable(false)
alert.show()
}
private fun selectPicture() {
photo = createTempFile(photo)
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent, SELECT_PHOTO)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val dataUri = data!!.data
var bitmap: Bitmap = MediaStore.Images.Media.getBitmap(contentResolver, dataUri)
// Scale down bitmap size
bitmap = scaleBitmapDown(bitmap, 640)
myImageView!!.setImageBitmap(bitmap)
convertIntoBase(bitmap)
}
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)
}
private fun convertIntoBase(bitmap: Bitmap) {
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
val imageBytes: ByteArray = byteArrayOutputStream.toByteArray()
val base64encoded = Base64.encodeToString(imageBytes, Base64.NO_WRAP)
requestJsonToCloud(base64encoded)
}
private fun requestJsonToCloud(base64encoded: String) {
val image = JsonObject()
image.add("content", JsonPrimitive(base64encoded))
request.add("image", image)
val feature = JsonObject()
feature.add("type", JsonPrimitive("TEXT_DETECTION"))
val features = JsonArray()
features.add(feature)
request.add("features", features)
val imageContext = JsonObject()
val languageHints = JsonArray()
languageHints.add("en")
imageContext.add("languageHints", languageHints)
request.add("imageContext", imageContext)
}
private fun processImage() {
annotateImage(request.toString())
.addOnCompleteListener { task ->
if (!task.isSuccessful) {
val e = task.exception
if (e is FirebaseFunctionsException) {
val code = e.code
val details = e.details
Log.w("exception code ", "$code")
Log.w("exception details", "$details")
}
showSnackbar("An error occurred.")
} else {
val annotation =
task.result!!.asJsonArray[0].asJsonObject["fullTextAnnotation"].asJsonObject
System.out.format("%nComplete annotation:")
System.out.format("%n%s", annotation["text"].asString)
}
}
}
private fun showSnackbar(message: String) {
Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_SHORT).show()
}
private fun createTempFile(fileClass: File?): File {
var file = fileClass
val directory =
File(Environment.getExternalStorageDirectory().path + "/jp.co.camrininfotech.mlText")
if (!directory.exists() || !directory.isDirectory) {
directory.mkdirs()
}
if (file == null) {
file = File(directory, "orig.jpg")
}
return file
}
private fun annotateImage(requestJson: String): Task<JsonElement> {
return functions
.getHttpsCallable("annotateImage")
.call(requestJson)
.continueWith { task ->
println("annotateImage result " + task.result.toString())
val result = task.result?.data
JsonParser.parseString(Gson().toJson(result))
}
}
private fun checkPermission(requestCode: Int) {
when (requestCode) {
WRITE_STORAGE -> {
val hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {
selectPicture()
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
requestCode
)
}
}
}
}
}
我正在使用这些依赖项
implementation 'com.google.firebase:firebase-auth-ktx'
implementation platform('com.google.firebase:firebase-bom:28.0.1')
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'com.firebaseui:firebase-ui-auth:7.1.1'
implementation 'com.google.firebase:firebase-functions-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
预期行为
打印图像中的文本
其他上下文
W/exception代码:NOT_FOUNDW/exception详情:空
我找到了这个问题的解决方案。我没有在我的 firebase 云函数中上传 vision-annotate-images。
To deploy the function:
Clone or download the functions-samples repo and change to the vision-annotate-image directory:
git clone https://github.com/firebase/functions-samples
cd vision-annotate-image
Install dependencies:
cd functions
npm install
cd ..
If you don't have the Firebase CLI, install it.
Initialize a Firebase project in the vision-annotate-image directory. When prompted, select your project in the list.
firebase init
Deploy the function:
firebase deploy --only functions:annotateImage