【问题标题】:Converting an HEIC image to Jpg and upload to the Server in Xamarin iOS将 HEIC 图像转换为 Jpg 并上传到 Xamarin iOS 中的服务器
【发布时间】:2024-04-23 23:25:01
【问题描述】:

我正在尝试使用依赖服务将 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());
                }
            }

请告诉我我做错了什么以及如何实现这种转换和上传的可能方法。

谢谢,

【问题讨论】:

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


    【解决方案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[] 效率非常低,您可能只想将原始流传回并使用它来填充要发布的表单内容,只需让您 Dispose 它,否则您将泄漏本机分配...

    【讨论】:

      【解决方案2】:

      首先从 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 上传到服务器上。

      【讨论】:

        最近更新 更多