Преобразование изображения HEIC в Jpg и загрузка на сервер в Xamarin iOS

Я пытаюсь преобразовать изображение HEIC в Jpg из приведенного ниже кода при использовании службы зависимостей и пытаюсь отобразить изображение с загрузкой в ​​веб-API. Но оба не работают. Это правильный способ преобразования HEIC в Jpg? если нет, пожалуйста, предложите мне, как этого добиться.

Метод службы зависимостей:

public byte[] GetJpgFromHEIC(string path)
{
        byte[] imageAsBytes = File.ReadAllBytes(path);
        UIImage images = new UIImage(NSData.FromArray(imageAsBytes));
        byte[] bytes = images.AsJPEG().ToArray();
        // Stream imgStream = new MemoryStream(bytes);

        return bytes;
}

В коде Xaml за отображением изображения:

Image image = new Image(){};
byte[] bytes = DependencyService.Get<ICommonHelper>
                      ().GetJpgFromHEIC(fileData.FileName);
image.Source = ImageSource.FromStream(() => new MemoryStream(bytes));

Загрузка кода в веб-API: пробовали как в StreamContent, так и в ByteArrayContent как HttpContent, как показано ниже.

   HttpResponseMessage response = null;

    string filename = data.FileName; // here data object is a FileData, picked from using FilePicker.

    byte[] fileBytes = DependencyService.Get<ICommonHelper>().GetJpgFromHEIC(data.FilePath);

            HttpContent fileContent = new ByteArrayContent(fileBytes);

    // Stream fileStream = new MemoryStream(fileBytes);
    // HttpContent fileContent = new StreamContent(fileStream);

    fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name =         
             "file", FileName = data.FileName };
    fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
            using (var formData = new MultipartFormDataContent())
            {
                formData.Add(fileContent);
                response = await client.PostAsync(uri, formData);
                if (response.IsSuccessStatusCode)
                {
                    Debug.WriteLine(@" Upload CommentsAttachments SUCCESS>> " + response.Content.ToString());
                }
            }

Пожалуйста, предложите мне, что я делаю неправильно и как добиться и возможные способы для этого преобразования и загрузки.

Спасибо,


person Ganesh    schedule 09.01.2019    source источник


Ответы (2)


Нечто подобное работает для пути/файла HEIC (или любого допустимого формата изображения, поддерживаемого iOS). Я использую образец autumn_1440x960.heic.

using (var image = UIImage.FromFile(path))
using (var jpg = image.AsJPEG(0.5f))
using (var stream = jpg.AsStream())
{
    // do something with your stream, just saving it to the cache directory as an example...

    using (var cache = NSFileManager.DefaultManager.GetUrl(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomain.All, null, true, out var nsError))
    using (var fileStream = new FileStream(Path.Combine(cache.Path, "cache.jpg"), FileMode.Create, FileAccess.Write))
    {
        stream.CopyTo(fileStream);
        imageView1.Image = UIImage.FromFile(Path.Combine(cache.Path, "cache.jpg"));
    }
}

К вашему сведению: копирование byte[] вокруг очень неэффективно, вы можете просто передать исходный поток обратно и использовать его для заполнения содержимого формы для публикации, просто заставьте вас удалить его, иначе вы потеряете собственные выделения...

person SushiHangover    schedule 09.01.2019

Сначала извлеките сжатый поток изображений из heic пути к изображению и сохраните его в другом месте, чтобы загрузить на сервер. Вот код для сохранения сжатого изображения из изображений высокой четкости:

public async Task<Stream> RetriveCompressedImageStreamFromLocation(string location)
    {
        Stream imgStream = null;
        try
        {
            byte[] imageAsBytes = File.ReadAllBytes(location);
            UIKit.UIImage images = new UIKit.UIImage(Foundation.NSData.FromArray(imageAsBytes));
            byte[] bytes = images.AsJPEG(0.5f).ToArray();
            Stream imgStreamFromByte = new MemoryStream(bytes);
            imgStream = imgStreamFromByte;
            return imgStream;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
        return imgStream;
    }

Затем сохраните этот поток в нужном месте и извлекайте из него при необходимости.

public async Task<string> SaveImageFile(Stream StreamToWrite)
    {
        string savedImgFilePath = string.Empty;
        try
        {
            byte[] imgByteData = null;
            using (MemoryStream ms = new MemoryStream())
            {
                StreamToWrite.CopyTo(ms);
                imgByteData = ms.ToArray();
            }

            string FileName = “MyImg.jpg";
            var Docdirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var directory = Docdirectory + “/MyImages”;

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
            var path = Path.Combine(directory, FileName);
            if (File.Exists(path))
            {
                File.Delete(path);
            }
            File.WriteAllBytes(path, imgByteData);
            Debug.WriteLine(“Image File Path=== " + path);
            savedImgFilePath = path;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
        return savedImgFilePath;
    }

Теперь просто нужно получить байты из сохраненного пути и передать его для загрузки на сервер как MultipartFormDataContent.

person Nidhi Kayasth    schedule 30.09.2020