Как преобразовать строку изображения в целое число на Android?

# #firebase #kotlin #google-maps-markers #android-canvas #android-bitmap

Вопрос:

Я хочу извлечь изображение из Firebase и поместить его на холст, чтобы использовать его для размещения в пользовательском маркере Google. Я получаю ошибку, когда использую метод .toInt (). Может быть, это неправильный способ сделать это.

Код:

 var loggedInUser : User = User()

                            mFireStore.collection(Constants.USERS)
                                    .document(FirestoreClass().getCurrentUserId())
                                    .get()
                                    .addOnSuccessListener { document ->
                                        loggedInUser = document.toObject(User::class.java)!!
                                    }
                            canvas1.drawBitmap(BitmapFactory.decodeResource(resources,loggedInUser.image.toInt()), 0F, 0F, color)
                            canvas1.drawText("User Name!", 30F, 40F, color)




                            // add marker to Map

                            // add marker to Map
                            markerOptions
                                    .position(LatLng(mLastLocation!!.latitude, mLastLocation!!.longitude))
                                    .title("Current Location")
                                    /*.snippet(address)*/
                                    .icon(BitmapDescriptorFactory.fromBitmap(bmp))

                            mCurrentMarker = googleMap.addMarker(markerOptions)
 

Logcat, в котором я получаю ошибку:

 2021-07-06 19:33:54.839 10676-10676/com.example.aroundyouapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.aroundyouapp, PID: 10676
java.lang.NumberFormatException: For input string: ""
    at java.lang.Integer.parseInt(Integer.java:627)
    at java.lang.Integer.parseInt(Integer.java:650)
    at com.example.aroundyouapp.activities.MainActivity$getCurrentLocation$1.onLocationResult(MainActivity.kt:394)
    at com.google.android.gms.internal.location.zzau.notifyListener(Unknown Source:4)
    at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(com.google.android.gms:play-services-base@@17.1.0:17)
    at com.google.android.gms.common.api.internal.ListenerHolder$zaa.handleMessage(com.google.android.gms:play-services-base@@17.1.0:6)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at com.google.android.gms.internal.base.zar.dispatchMessage(com.google.android.gms:play-services-base@@17.1.0:8)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 

Как я могу преобразовать изображение в строковом формате(т. Е. loggedInUser.image) в Int, чтобы изображение было помещено на холст? Может быть, это глупый вопрос, но я новичок в этом, так что да.

Заранее спасибо

Правка 1:

Код, который я использую для отображения изображения профиля пользователя в меню навигации:

 fun loadUserData(activity: Activity){
    //This function is called in MainActivity in the onCreate method.
    mFireStore.collection(Constants.USERS)
        .document(getCurrentUserId())
        .get()
        .addOnSuccessListener { document ->
            val loggedInUser = document.toObject(User::class.java)

            when(activity){
                is MyProfileActivity -> {
                    activity.setUserDataInUI(loggedInUser!!)
                }
                is MainActivity -> {
                    activity.updateNavigationUserDetails(loggedInUser!!)
                }
            }
        }
}

fun updateNavigationUserDetails(user: User){
    hideProgressDialog()
    mUserName = user.name
    Glide
            .with(this)
            .load(user.image)
            .centerCrop()
            .placeholder(R.drawable.ic_user_place_holder)
            .into(nav_user_image)

    tv_username.text = user.name
}
 

Edit 2:

I tried Ragu’s answer. The app crashed after trying it.

This is the error in the logcat.

 2021-07-14 19:07:04.779 18663-18663/com.example.aroundyouapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.aroundyouapp, PID: 18663
java.lang.NumberFormatException: For input string: "https://firebasestorage.googleapis.com/v0/b/aroundyou-5f1d2.appspot.com/o/USER_IMAGE1624282533208.jpg?alt=mediaamp;token=731ea81d-32a0-4378-aa7b-0d7764260e41"
    at java.lang.Integer.parseInt(Integer.java:615)
    at java.lang.Integer.parseInt(Integer.java:650)
    at com.example.aroundyouapp.activities.MainActivity$getCurrentLocation$1$onLocationResult$1.onSuccess(MainActivity.kt:374)
    at com.example.aroundyouapp.activities.MainActivity$getCurrentLocation$1$onLocationResult$1.onSuccess(MainActivity.kt:349)
    at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 

В прошлый раз я получил ту же ошибку, но на этот раз ссылка на изображение отображается в logcat

Правка 3

Получил эту ошибку после попытки обновить ответ 2 от Ragu

 2021-07-14 20:05:57.399 20234-20234/com.example.aroundyouapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.aroundyouapp, PID: 20234
android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1565)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
    at java.net.InetAddress.getAllByName(InetAddress.java:1152)
    at com.android.okhttp.Dns$1.lookup(Dns.java:41)
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:178)
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:86)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:176)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:248)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:211)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:30)
    at com.example.aroundyouapp.activities.MainActivity$getCurrentLocation$1$onLocationResult$1.onSuccess(MainActivity.kt:379)
    at com.example.aroundyouapp.activities.MainActivity$getCurrentLocation$1$onLocationResult$1.onSuccess(MainActivity.kt:352)
    at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 

Комментарии:

1. Пожалуйста, уберите . toInt() из loggedInUser.image. toInt()

2. Если я этого не добавлю, то там будет написано «Требуется: Int, найдено: строка». Не могли бы вы помочь мне с этим, пожалуйста?

3. Просто проверьте наличие пустой строки в этом случае.. если ( loggedInUser.image.toString(),длина() > 0) { canvas1.drawBitmap(BitmapFactory.decodeResource(ресурсы,loggedInUser.image. toInt()), 0F, 0F, цвет) }

4. Теперь маркер не отображается, лол

5. Я думаю, что изображение в строковом формате находится определенным образом? и, может быть, мы не можем просто преобразовать его в Int и заставить его работать, я думаю?

Ответ №1:

Предположим, вы пытаетесь отобразить изображение в Base64 формате.

Декодируйте входящую Base64 строку в ByteArray

 val imageByteArray = Base64.decode(user.image, Base64.DEFAULT)
 

Затем загрузите imageByteArray в Glide , как показано ниже.

 Glide
   .with(this)
   .asBitmap()
   .load(imageByteArray)  // ==> Pass the ByteArray here  
   .into(nav_user_image)
 

ПРАВКА 1 : Обновленный ответ

Из вашего кода я вижу, что код рисования на холсте размещен за пределами addOnSuccessListener от snapshots . Но вы получаете доступ к полям loggedInUser до завершения addOnSuccessListener , где назначены данные.

addOnSuccessListener является async операцией и не будет выполняться последовательно, как вы написали в своем существующем коде.

Переместите следующий код внутрь addOnSuccessListener .

 canvas1.drawBitmap(BitmapFactory.decodeResource(resources,loggedInUser.image.toInt()), 0F, 0F, color)
canvas1.drawText("User Name!", 30F, 40F, color)
 

Ваш существующий код.

  mFireStore.collection(Constants.USERS)
                                    .document(FirestoreClass().getCurrentUserId())
                                    .get()
                                    .addOnSuccessListener { document ->
                                        loggedInUser = document.toObject(User::class.java)!!
                                    }
                            canvas1.drawBitmap(BitmapFactory.decodeResource(resources,loggedInUser.image.toInt()), 0F, 0F, color)
                            canvas1.drawText("User Name!", 30F, 40F, color)
 

Обновленный ответ 2 :

На основе журнала ошибок изображение извлекается в виде удаленного URL-адреса, который может быть непосредственно загружен в ImageView . Но когда вы пытаетесь нарисовать его в canvas , вам нужно декодировать файл с удаленного URL-адреса как stream , а затем установить его в Canvas .

Что-то вроде ниже

 URL url = new URL(<PASS YOUR URL from FIREBASE>);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 ....
Bitmap receivedImageasBitmap = BitmapFactory.decodeStream(connection .getInputStream());
.. 
canvas1.drawBitmap(receivedImageasBitmap)
 

Комментарии:

1. Я попробовал. Я не использую Glide, потому что хочу нарисовать это изображение на холсте, поэтому, когда я попробовал ваше решение, в нем говорилось, что «ByteArray» Требуется «Int» в этой строке кода. canvas1.drawBitmap(BitmapFactory.decodeResource(resources,imageByteArray), 0F, 0F, color)

2. Проверьте мой обновленный ответ и сообщите, если это сработает ! @perpetualdarkness

3. Эй, я попробовал твой код, и приложение вышло из строя. Я обновил свой вопрос с ошибкой, которую я получил в logcat.

4. Проверьте мой обновленный ответ 2 @perpetualdarkness

5. попробовал. снова произошла ошибка. пожалуйста, проверьте обновленный вопрос