Pobieranie obrazka z webapi

0

Cześć, mam problem z pobraniem obrazka z webapi:

Serwer:
IMToken: 123123123 uin: 123 user-agent:...

Returns an unpackaged image with a heading Content-type: image/png

Nagłówek który dostaję :

Cache-Control: public, max-age=86400
Connection: Keep-Alive
Date: Fri, 30 Nov 2018 1208 GMT
Keep-Alive: timeout=5, max=99
OkHttp-Received-Millis: 1543581128745
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1543581128514 Server: Apache/2.4.33 (Amazon) OpenSSL/1.0.2k-fips PHP/7.0.30 X-Powered-By: PHP/7.0.30
Content-Length: 26190
Content-Type: image/png
Keep-Alive: timeout=5, max=99
OkHttp-Received-Millis: 1543581128745
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1543581128514
X-Powered-By: PHP/7.0.30

klasa menager odpowiedzialna z pobranie obrazka:

public async Task<Image> GetAvatar(string dpi, Int64 uin)
{
    var response = await BasicRequestAsync(string.Format(AVATAR_URL, dpi, uin), HttpMethod.Get, true, null, null, false);

    if (response == null) 
         return null;

    var stream = await response.Content.ReadAsByteArrayAsync();

    Image image = new Image();

    image.Source = ImageSource.FromStream(() => new MemoryStream(stream));

    return image;
}

cześć klasy ViewModel:

 private Image _avatarImage;
        public Image AvatarImage
        {
            get => _avatarImage;
            set
            {
                if(_avatarImage == value) return;
                _avatarImage = value;
                OnPropertyChanged();
            }
        }
        #endregion

        #region Methods
        public AvatarPageViewModel(INavigation navigation) : base(navigation)
        {
            InitializeAvatarData();
        }

      private async void InitializeAvatarData()
        {
            if (AvatarItems == null)
            {
                AvatarItems = new ObservableCollection<AvatarModel>();

               var AvatarImage = await AvatarManagerInstance.GetAvatar(DependencyService.Get<IDisplayInfo>().GetDisplayDpi(), 2);

                var list = await AvatarManagerInstance.GetAvatars(DependencyService.Get<IDisplayInfo>().GetDisplayDpi());

                if (list == null) return;

                AvatarItems.Clear();
                AvatarItems.AddRange(list);
            }
        }
0

Masz problem z samym WebApi, czy pobraniem tego w Xamarinie, a WebApi poprawnie zwraca plik?

0
error91 napisał(a):

Masz problem z samym WebApi, czy pobraniem tego w Xamarinie, a WebApi poprawnie zwraca plik?

Z serwerwa pobiera dostaje kod 200 OK i ten nagłowek co wyżej. Ale mam problem z wyświetleniem. Pierwszy raz pobieram obrazek z webapi wcześniej robiłem to przy uzyciu base64 i tu nie było żadnych problemów

0

Gdzie dostajesz ten błąd ? Przy odczycie bajtów ?

0

A z webapi możesz odczytać obrazek? Pobierz go curlem i sprawdź czy wyświetla się poprawnie.

0

Jak mogę zapisać sobie mój stream jako png do urządzenia aby sprawdzić czy obrazek jest poprawny ? Może to pomoże będę wiedział mniej wiecej gdzie jest cos nie tak

0

https://www.google.nl/search?q=stream+to+png+c%23&oq=stream+to+png+c%23&aqs=chrome..69i57j0l3.2750j0j7&sourceid=chrome&ie=UTF-8

https://stackoverflow.com/questions/18134234/how-to-convert-system-io-stream-into-an-image

var img = Bitmap.FromStream(stream);

https://docs.microsoft.com/en-us/xamarin/android/platform/files/

0

stworzyłem customwą klasę w projekcie androidowym ale mam problem z dostaniem sie do scieżki.
Bitmap bitmap = BitmapFactory.DecodeByteArray(stream, 0, stream.Length);

        var directoryPicture = Android.OS.Environment.DirectoryMusic;
        var filePath = System.IO.Path.Combine(directoryPicture, "Avatar.png");
        var pathStream = new FileStream(filePath, FileMode.Create);
        bitmap.Compress(Bitmap.CompressFormat.Png, 100, pathStream);
        pathStream.Close();

Głownym moim problemem jest to że kod z początka postu nie wyswietla mi w xamlu obrazu ale nie wiem dla czego. Dla tego chciałem po drodze zapisać obraz i sprawdzić czy to wina samego pobierania z webapi czy gdzieś indziej?

2

Sprawdź, czy z API dostajesz poprawną tablicę bajtów i czy poprawnie bindujesz wszystko, bo taki super prosty kod jak najbardziej działa w Xamarinie:

private async void Button_Clicked(object sender, EventArgs e)
{
    image.Source = await ReturnImageSource();
}

private static async Task<ImageSource> ReturnImageSource()
{
    var hc = new HttpClient();
    var bytes = await hc.GetByteArrayAsync("https://static.4programmers.net/uploads/photo/573b5d9eaf6f9.jpg");
    return ImageSource.FromStream(() => new MemoryStream(bytes));
}
<StackLayout>
    <!-- Place new controls here -->
    <Image x:Name="image" />
    <Button Clicked="Button_Clicked" Text="Pobierz obrazek" />
</StackLayout>

////

Do odczytania pliku z dysku wykorzystaj File.ReadAllBytes, bo AFAIR Image przyjmuje jako źródło ImageSource i sam wykonuje konwersję z odpowiedniego formatu, wystarczy, że dostanie strumień bajtów.

2

Moment, a czy twój problem nie polega czasem na tym, że:

var AvatarImage = await AvatarManagerInstance.GetAvatar(DependencyService.Get<IDisplayInfo>().GetDisplayDpi(), 2);

I tworzysz nową zmienną AvatarImage, a nie zapisujesz do właściwości o nazwie AvatarImage?

0

@Ktos:

    <ContentPage.Content>
        <Image Source="{Binding AvatarImage}"/>
    </ContentPage.Content>
</d:ExtendedContentPage>
2

No to trudno, aby to zadziałało, bo atrybut Source typu Image oczekuje obiektu typu ImageSource, a ty mu dajesz typ Image.

Zrób tak:

private ImageSource _avatarImage;
public ImageSource AvatarImage
{
	get => _avatarImage;
	set
	{
		if(_avatarImage == value) return;
		_avatarImage = value;
		OnPropertyChanged();
	}
}

public async Task<ImageSource> GetAvatar(string dpi, Int64 uin)
{
    var response = await BasicRequestAsync(string.Format(AVATAR_URL, dpi, uin), HttpMethod.Get, true, null, null, false);
 
    if (response == null) 
         return null;
 
    var stream = await response.Content.ReadAsByteArrayAsync();
    return ImageSource.FromStream(() => new MemoryStream(stream));
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1