0

Мне нужно загрузить изображение с веб-сервера api в мое приложение Xamarin.Forms. Картинка хранится в хранилище Azure Blob.Загрузка изображений из Web Api в Xamarin.Forms

Это мой метод Web Api:

[HttpGet("{id}")] 
public HttpResponseMessage Get(int id) 
{ 
    // Retrieve storage account from connection string. 
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("ConnectionString"); 

    // Create the blob client. 
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); 

    // Retrieve reference to a previously created container. 
    CloudBlobContainer container = blobClient.GetContainerReference("picturecontainer"); 

    // Retrieve reference to a blob named "photo.jpg". 
    CloudBlockBlob blockBlob = container.GetBlockBlobReference("picture"); 

    var stream = new MemoryStream(); 

    blockBlob.DownloadToStream(stream); 

    Image image = Image.FromStream(stream); 
    MemoryStream memoryStream = new MemoryStream(); 
    image.Save(memoryStream, ImageFormat.Jpeg); 

    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
    result.Content = new ByteArrayContent(memoryStream.ToArray()); 

    result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); 

    return result; 
} 

В моем приложении я пытаюсь загрузить байты изображения с помощью следующего кода:

public App() 
{ 
    _client = new HttpClient(); 
    _client.MaxResponseContentBufferSize = 256000; 

    Button downloadImageBtn = new Button() { 
     Text = "Download Image", 
    }; 
    var image = new Image() { 
     Source = ImageSource.FromUri (new Uri ("http://www.engraversnetwork.com/files/placeholder.jpg")), 
     Aspect = Aspect.AspectFit 
    }; 
    downloadImageBtn.Clicked += async (object sender, EventArgs e) => { 
     var values = await handleClick (sender, e); 
     uploadPicButton.Text = values; 
     var imageBytes = await downloadPicture(); 
     image.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes)); 
    }; 

    MainPage = new ContentPage { 
     Content = new StackLayout { 
      VerticalOptions = LayoutOptions.Center, 
      Children = { 
       image, 
       downloadImageBtn 
      } 
     } 
    }; 
} 

private async Task<byte[]> downloadPicture() 
{ 
    var uri = new Uri (string.Format (RestUrl, "5")); 
    //return await _client.GetByteArrayAsync (uri); 
    var response = await _client.GetAsync (uri); 
    if (response.IsSuccessStatusCode) { 
     var content = await response.Content.ReadAsByteArrayAsync(); 
     return content; 
    } 
    throw new HttpRequestException(); 
} 

Однако, когда я нажимаю на кнопку, заполнитель изображение исчезает. Есть ли проблема при отправке изображения с сервера или при его получении в приложении?

+0

Вы не показываете код downloadPicture, поэтому я не знаю, находится ли проблема внутри этой функции. Попробуйте отладить. Поместите точку останова после получения изображения. Сколько байтов есть? Действительно ли это пустая или пустая? Соответствует ли размер вашей фотографии? – Grisha

+0

@Grisha Я добавил код 'downloadPicture()' к вопросам. Однако, когда изображение отправляется с сервера, тело контента имеет около 170 тыс. Байт, но есть только 265 возвращенных байтов изображения. –

+0

Хорошо, мы ближе. Теперь проверьте на стороне сервера, в функции Get, сколько байтов вы отправляете. Проверьте результат. Контент. – Grisha

ответ

0

После строки blockblob.DownloadToStream попробуйте установить Position of the stream в 0. Я не знаком с API Azure, но я думаю, что это может помочь.

Кроме того, попробуйте использовать ReadAsStreamAsync вместо ReadAsByteArrayAsync в вашей функции downloadPicture. Что-то вроде этого:

var responseStream = await response.Content.ReadAsStreamAsync(); 
byte[] buf = new byte[512]; 
int bufSize; 
while((bufSize = (await responseStream.ReadAsync(buf, 0, buf.Length))) > 0) 
{ 
    // store the received bytes to some buffer until the file is fully downloaded 
} 

Вы получаете весь свой контент таким образом?

+0

Я пробовал, но результат до сих пор. –

1

Я бы не реализовал загрузку изображений вручную.

Если вы хотите загрузить больше изображений и/или разрешить отображение заполнителя во время загрузки, я рекомендую библиотеку FFImageLoading. Он предлагает отличные функциональные возможности, такие как загрузка, кеширование, отображение замеров и изображений ошибок и самое главное: сбрасывать выборку изображения до целевого размера. Это всегда боль в андроиде. Он доступен для собственных проектов xamarin UI и для Xamarin.Froms.

Вы можете привязывать строки, содержащие URL-адреса, непосредственно к источнику. Код хотел бы:

<ffimageloading:CachedImage 
    Source="http://thecatapi.com/?id=MTQ5MzcyNA"> 
</ffimageloading:CachedImage> 

 Смежные вопросы

  • Нет связанных вопросов^_^