Loading image from firebase storage not loading image using glide using Kotlin - kotlin

I am trying to load an image from Firebase Storage using Kotlin and Glide. i added all the dependecies and apply plugin:
implementation 'com.firebaseui:firebase-ui-storage:6.2.0'
implementation 'com.google.firebase:firebase-storage-ktx:19.1.1'
implementation 'com.github.bumptech.glide:glide:4.8.0'
kapt 'com.github.bumptech.glide:compiler:4.9.0'
apply plugin: 'kotlin-kapt'
My code is as follows:
val storageRef = Firebase.storage.reference
val imageref = storageRef.child("test/test.jpg")
imagetest = findViewById(R.id.imageView5)
Glide.with(this)
.load(imageref)
.into(imagetest)
When running the code, the imageview which had a default image goes black indicating that the code is trying to retrieve something from Firebase Storage. but the imageView never populates the downloaded image. assuming the download actually happens.
Am I doing something wrong? my firebase Storage screenshot is below:
I have tested this a little bit more, and Glide seems to load images from HTTPS ok, regardless of where i pull the URL from. But cloud storage provide URL as GS://. so how do i convert the GS:// to HTTPS://?
Please help.

I Figured it out.
imageref = Firebase.storage.reference.child("test/test.jpg")
imageref.downloadUrl.addOnSuccessListener {Uri->
val imageURL = Uri.toString()
imagetest = findViewById(R.id.imageView5)
Glide.with(this)
.load(imageURL)
.into(imagetest)
}
the 'downloadurl' statement actually converts the GS:// to HTTPS://

The difference between the both:
GS URL:
gs://<your_project_id>.appspot.com/test/test.jpg
HTPPS URL:
https://firebasestorage.googleapis.com/v0/b/<your_project_id>.appspot.com/o/test%2Ftest.jpg

Here is the process where my problem fixed -
Step 1 - go to build.gradle(app) and add these dependency
implementation 'com.firebaseui:firebase-ui-storage:4.3.2'
implementation 'com.github.bumptech.glide:glide:4.x.x'
annotationProcessor 'com.github.bumptech.glide:compiler:4.x.x'
Step 2 -
Create a java file
#GlideModule
public class MyAppGlideModule extends AppGlideModule {
#Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.append(StorageReference.class, InputStream.class,
new FirebaseImageLoader.Factory());
}
}
Step 3 - Set image where you want
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-app>/").child("folder"); //add .child(nested_folder) if nested folder occurs
GlideApp.with(context)
.load(storageRef.child(test_image.jpg))
.into(holder.thumbnail);
//that .load() will be load like .load(gs://<your_app/folder/test_image.jpg>)

Related

Receive video from a source, preprocess and stream live preview to the client | ASP.NET Core

I need to implement a server that gets video from some source for example IPCamera
then preprocess the image and streams it down to the client (if requested).
I already implemented the part with processing, it accepts a single frame (bitmap) and returns the processed bitmap. What I'm struggling with is the part of receiving video from the camera and then streaming it to the client.
What would be the right way to do it?
What libraries do you recommend using?
I use ASP.NET Core for the Server part, and Angular/React for the Client.
I tried to implement gRPC but a gRPC-Web client for typescript seems to be a pain in the ass.
Edit: 02.08.2022
What I achieved so far:
I figured out how to receive image output from the camera.
I found out RTSP Client for C#. Source: C# RTSP Client for .NET
It works pretty fine. I can receive output with small to no delay, and I use my phone to emulate the RTSP camera/server.
So RTSP Client receives raw frames (in my case H.264 IFrame/PFrame). The problem is I need to decode those frames preferably to Bitmap because I use YoloV4 ONXX Model for object detection.
Here's how I set up YoloV4 with ML.Net. Source: Machine Learning with ML.NET – Object detection with YOLO
To decode raw frames I use FFMpeg (sadly I didn't find any working FFMpeg package that would work with .NET Core, I tried AForge.Net, Accord but in both packages, the FFMPEG namespace is missing after installing for some reason, so I dug through Github and took this project FrameDecoderCore). It's not the best solution but it works. Now I can receive the output and decode it to Bitmap.
Now I'm facing three major issues:
How to detect objects without delaying the process of receiving camera output. And how to properly build an onnx model just to predict without training.
How to convert processed bitmaps back to a video stream. I also need to be able to save part of it as a video file on disk (video format doesn't matter) whenever the desired object was detected.
How to stream processed or unprocessed output to the client when the client wants to see the camera output. - I'm thinking of gRPC here and sending bitmaps and then displaying it on HTML Canvas.
Here's how my service looks at the moment:
public class CCTVService : BackgroundService
{
private readonly RtspClient _rtspClient;
private readonly ILogger<CCTVService> _logger;
private const int streamWidth = 480;
private const int streamHeight = 640;
private static readonly FrameDecoder FrameDecoder = new FrameDecoder();
private static readonly FrameTransformer FrameTransformer = new FrameTransformer(streamWidth, streamHeight);
public CCTVService(ILogger<CCTVService> logger)
{
_logger = logger;
_rtspClient = new RtspClient(new ConnectionParameters(new Uri("rtsp://192.168.0.99:5540/ch0")));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (_rtspClient)
{
try
{
await _rtspClient.ConnectAsync(stoppingToken);
_logger.LogInformation("Connecting to RTSP");
}
catch(RtspClientException clientException)
{
_logger.LogError(clientException.Message);
//throw;
}
_rtspClient.FrameReceived += (obj, rawFrame) =>
{
if (rawFrame is not RawVideoFrame rawVideoFrame)
return;
var decodedFrame = FrameDecoder.TryDecode(rawVideoFrame);
if (decodedFrame == null)
return;
using var bitmap = FrameTransformer.TransformToBitmap(decodedFrame);
_logger.LogInformation($"Timestamp: {new DateTimeOffset(rawFrame.Timestamp).ToUnixTimeSeconds()} Timestamp-diff: {new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds() - new DateTimeOffset(rawFrame.Timestamp).ToUnixTimeSeconds()}");
// save bitmaps | Test
//var t = new Thread(() =>
//{
// using var bitmap = FrameTransformer.TransformToBitmap(decodedFrame);
// var name = "./test/" + new DateTimeOffset(rawFrame.Timestamp).ToUnixTimeMilliseconds().ToString() + " - " + new Random().NextInt64().ToString() + ".bmp";
// bitmap.Save(name);
//});
//t.Priority = ThreadPriority.Highest;
//t.Start();
};
try
{
await _rtspClient.ReceiveAsync(stoppingToken);
}
catch
{
// swallow
}
}
}
}
So I can't really help with part 2 and 3 of your question but with ML.NET, one of the things you might consider is batching the predictions. Instead of preprocessing them one at a time, you could collect 10-20 frames and then instead of using PredictionEngine, use the Transform passing it in an IDataView instead of a Bitmap.
Here are some samples of using ONNX models inside applications. The WPF sample might be of interest since it uses a webcam to capture inputs. I believe it uses the native Windows APIs, so different than how you'd do it for web but it might be worth looking at anyway.
https://github.com/dotnet/machinelearning-samples/tree/main/samples/csharp/end-to-end-apps/ObjectDetection-Onnx

Getting Profile Photo from Microsoft Graph API for Android

I have recently started working on an android project that uses Microsft authentication and graph API. By following this:
https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-android
I am able to authenticate and get some data from graph API. Now I want to load the profile photo of Microsoft account in the app. For this purpose, I used ProfilePhoto object with a call back as follows:
graphClient
.me()
.photo()
.buildRequest()
.get(new ICallback<ProfilePhoto>() {
#Override
public void success(ProfilePhoto profilePhoto) {
Log.d(TAG, "Found " + profilePhoto.getRawObject().toString());
}
#Override
public void failure(ClientException ex) {
displayError(ex);
}
});
Here profilePhoto.getRawObject() returns a json file like:
{"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('hanzla_hawk%40outlook.com')/photo/$entity","#odata.mediaContentType":"image/png","#odata.mediaEtag":"W/\"8050a078da935403cf67163f23f1baace5c7abf3ff784452cb08c38660308a83\"","id":"default","height":256,"width":256}
With this Json, how can I load the image into an image view? I have previous experience with Picasso and other fake apis. But right now I just dont know what should I pass in the Picasso to load image from this json.
I have just make a call to get a profile photo to show on an Android app using Jetpack Compose views in Kotlin. To achieve it I have followed your question and this tutorial:
https://learn.microsoft.com/en-us/graph/tutorials/android
You almost got it. Just add .content() call between .me().photo() and .buildRequest().
This is my code on my project to get the photo content:
// GET /me/photo/$value (logged in user)
fun getUserPhoto(
onGotPhoto: (ImageBitmap) -> Unit,
onGotError: (Exception) -> Unit
) {
mClient!!.me().photo().content().buildRequest()
.async
.thenAccept { inputStream ->
val bitmap = BitmapFactory.decodeStream(inputStream).asImageBitmap()
onGotPhoto.invoke(bitmap)
}
.exceptionally { processError(it, onGotError) }
}

How to make chloropleth using Mapbox for Andriod, where the data comes in a GEOJSON

After getting a GEOJSON file which has all the boundaries of each country. From: https://datahub.io/core/geo-countries#data
How does one make a chloropleth using Mapbox, for a Andriod application being built using Kotlin.
private fun drawBoundaries(){
mapboxMap.getStyle {
try {
val source = GeoJsonSource("geojson-source", URI("assets://countries.geojson"))
it.addSource(source)
} catch (exception: URISyntaxException) {
Log.d(TAG, exception.toString())
}
}
}
And I am guessing fill is as follows in the link: https://docs.mapbox.com/android/maps/overview/data-driven-styling/#fill
mapboxMap.getStyle {
val fillLayer = FillLayer("layer-id", "source-id")
fillLayer.setProperties(PropertyFactory.fillColor(Color.GREEN))
it.addLayer(fillLayer)
}
Yes, FillLayer will be used and then you'll need to style it based on your data.
See https://docs.mapbox.com/android/maps/examples/join-local-json-data-with-vector-tile-geometries and https://docs.mapbox.com/android/maps/examples/update-by-zoom-level
Edit: Hm, looks like a video's missing for https://docs.mapbox.com/android/maps/examples/join-local-json-data-with-vector-tile-geometries.
https://imgur.com/a/THn7EoO shows what the example looks like.

Kotlin - get Firebase Image DownloadUrl returns "com.google.android.gms.tasks.zzu"

I am trying to upload images to Real time Firebase Database by creating two folders using Compressor library and need to display image like messenger with username but i am unable to display image due to url issue
var filePath = mStorageRef!!.child("chat_profile_images")
.child(userId + ".jpg")
//Create another directory for thumbimages ( smaller, compressed images)
var thumbFilePath = mStorageRef!!.child("chat_profile_images")
.child("thumbs")
.child(userId + ".jpg")
filePath.putFile(resultUri)
.addOnCompleteListener{
task: Task<UploadTask.TaskSnapshot> ->
if (task.isSuccessful) {
//Let's get the pic url
var donwloadUrl = task.result?.storage?.downloadUrl.toString()
Log.d(TAG, "Profilepic link: $donwloadUrl")
//Upload Task
var uploadTask: UploadTask = thumbFilePath
.putBytes(thumbByteArray)
uploadTask.addOnCompleteListener{
task: Task<UploadTask.TaskSnapshot> ->
var thumbUrl = task.getResult()?.storage?.downloadUrl.toString()
Log.d(TAG, "Profilepic link: $thumbUrl")
i tried to change downloadUrl
filepath.downloadUrl.toString
thumbFilePath.downloadUrl.toString
but both these values getting "com.google.android.gms.tasks.zzu"
i also tried to change
task.result.sessionurl.downloadUrl.toString
for this one i am getting downloadUrl but not a complete solution for my problem as still i cannot display image i need to get thumbUrl downloadUrl
You have the exact same and very common misunderstanding as in this question, except it's in java. You should follow the documentation here to understand get getDownloadUrl works. As you can see from the linked API documentation, it's not a property getter, it's actually a method that returns a Task<Uri> that tracks the asynchronous fetch of the URL you want, just like the upload task:
filePath.downloadUrl
.addOnSuccessListener { urlTask ->
// download URL is available here
val url = urlTask.result.toString()
}.addOnFailureListener { e ->
// Handle any errors
}
This will only work after the upload is fully complete.
Correct way of getting download link after uploading
here
Just putting out there, I also encounter the same problem,
but both these values getting "com.google.android.gms.tasks.zzu"
but it wasn't the same mistake from the OP
used addOnCompleteListener instead of addOnSuccesslistener
My Error code:
imageRef.downloadUrl.addOnCompleteListener { url ->
val imageURL = url.toString()
println("imageURL: $imageURL , url: $url")
addUserToDatabase(imageURL)
}

Ktor - Static content routing

I would love to understand better how Ktor is handling the routing for static content. I have the following hierarchy in my static folder (working directory):
- static
- index.html
- (some files)
- static
- css (directory)
- js (directory)
- (some files)
I'd like to serve all of them. So I was using directly this code in routing:
static {
defaultResource("index.html", "static")
resources("static")
}
Which works very well, but the issue is that it's taking the hand on all requests including my small get:
get("/smoketest"){
call.respondText("smoke test!", ContentType.Text.Plain)
}
What would be the best to handle in general the static content in Ktor?
Here is the code
Thank you
I tried reproducing it locally and made it work with two different approaches.
Put one of these in your static block
file("*", "index.html") // single star will only resolve the first part
file("{...}", "index.html") // tailcard will match anything
Or, put the following get handler as your last route:
val html = File("index.html").readText()
get("{...}") {
call.respondText(html, ContentType.Text.Html)
}
The {...} is a tailcard and matches any request that hasn't been matched yet.
Documentation available here: http://ktor.io/features/routing.html#path
Edit:
For resources I made the following work:
fun Route.staticContent() {
static {
resource("/", "index.html")
resource("*", "index.html")
static("static") {
resources("static")
}
}
}
I can't see your static files in the repository, so here is what it looks like in my project: