将HEIC图像转换为Jpg并上传到Xamarin iOS中的服务器

时间:2019-01-09 05:35:43

标签: xamarin file-upload xamarin.ios image-conversion heic

我正在尝试使用依赖服务从下面的代码将HEIC图像转换为Jpg,并尝试与图像一起显示并上传到Web 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));

将代码上传到Web 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());
                }
            }

请建议我我在做什么错,以及如何实现以及进行此转换和上传的方式。

谢谢

2 个答案:

答案 0 :(得分:1)

类似的方法适用于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 []效率很低,您可能只想将原始流传递回去,并使用它来填充要发布的表单内容,只是让您处理它,否则会泄漏本机分配... < / p>

答案 1 :(得分:0)

首先从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内容传递到服务器即可。