Home > database >  Returning ImageSource from a Task - is this even possible?
Returning ImageSource from a Task - is this even possible?

Time:11-15

I seem to be going round in circles with this problem i'm having. The old code I was using is as follows:

private ImageSource LoadImg(string url)
    {
        WebClient MyWebClient = new WebClient();
        byte[] BytesFile = MyWebClient.DownloadData(url);
        Stream m2 = new MemoryStream(BytesFile);
        return ImageSource.FromStream(() => m2);

    }

And I could consume this really easily by just calling:

mainimg.Source = LoadImg(url);

Now I want to convert this into async and use httpClient as WebClient is being discontinued? So I tried doing this

private async Task<ImageSource> LoadImg2Async(url)
    {
        
        System.Diagnostics.Debug.WriteLine("Firing LoadImg2");
        var httpResult = await Client.GetAsync(url);
        using var resultStream = await httpResult.Content.ReadAsStreamAsync();
        //using var fileStream = File.Create(@"c:\dev\yaythisworks.png");
        //resultStream.CopyTo(fileStream);

        return ImageSource.FromStream(() => resultStream);

    }

Seems to make sense, at least a little bit. But, then how do I consume this return from a task? I have tried:

mainimg.Source = LoadImg2Async(url).Result;

but I can't get it to work

Does anyone have any ideas? I have honestly tried searching for answers on google this time, Can't find any answers on how to return from tasks.

Thank you so much

Andrew

CodePudding user response:

Thanks for everyone's help, you helped me get on the right path!

It looks like it is not possible to return a stream from httpClient, I'm not sure why. When I was fiddling round it looks like the stream may be empty?! Anyway, the only way I found around this was to return bytes.

I had to change the Task return type to byte, and then return ms.ToArray();

private async Task<byte[]> LoadImg2Async(string pathtopdf)
    {   System.Diagnostics.Debug.WriteLine(pathtopdf);
        string pdfpathcorr = pathtopdf.Replace(@"Y:\", roothttpaddy);
        string url = pdfpathcorr.Replace(@"\", "/");
        System.Diagnostics.Debug.WriteLine("Corrected URL STRING = "   url);
                       
        var httpResult = await Client.GetAsync(url);
        byte[] bytearray = await httpResult.Content.ReadAsByteArrayAsync();

        MemoryStream iStream = new MemoryStream(bytearray);
        PdfFixedDocument document = new PdfFixedDocument(iStream);
        PdfRendererSettings settings = new PdfRendererSettings();
        settings.DpiX = 10;
        settings.DpiY = 10;
        MemoryStream ms = new MemoryStream();
        PdfPageRenderer renderer = new PdfPageRenderer(document.Pages[0]);
        renderer.ConvertPageToImage(ms, PdfPageImageFormat.Png, settings);
       

        //FileStream stm = File.OpenWrite(@"c:\dev\pdf "   fileid.ToString()   ".png");
        //renderer.ConvertPageToImage(stm, PdfPageImageFormat.Png, settings);
        ms.Position = 0;
       

 return ms.ToArray();
 
    }

Then to consume it I need to

byte[] bytearray = await LoadImg2Async(item.PDFPath);

MemoryStream stream = new MemoryStream(bytearray);

item.pdfpathconvert = ImageSource.FromStream(() => stream);

It does work, but it seems very clunky. I am reading bytes from httpClient, then putting it in a stream, then converting to image and returning bytes from async task, and then I have to put it into a new stream to convert it into an ImageSource.

Any tips or suggestions?

I know my code might not be the most streamlined, I was just trying to go through it in a logical way at the moment, but any tips would be welcomed.

Thanks

Andrew

  • Related