You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin iOS中如何将图片转换为HEIC/HEIF并压缩?

在Xamarin.Forms中实现HEIC/HEIF图片转换与压缩

由于HEIC/HEIF的支持具有平台依赖性,Xamarin.Forms本身没有跨平台原生API,需要通过依赖服务调用各平台原生能力来实现格式转换与压缩,同时替代原Plugin.Media的图片获取逻辑避免自动转JPG。

实现步骤

1. 定义跨平台依赖接口(共享项目)

先统一跨平台调用的接口:

public interface IImageHeicConverter
{
    // 输入源图片路径,输出HEIC格式图片路径,quality为压缩质量(0-100)
    Task<string> ConvertToHeicAsync(string sourceImagePath, int quality);
}

2. iOS平台实现(iOS项目)

iOS从iOS 11开始原生支持HEIC,使用CGImageDestination实现格式转换:

[assembly: Dependency(typeof(ImageHeicConverter_iOS))]
namespace YourAppNamespace.iOS
{
    public class ImageHeicConverter_iOS : IImageHeicConverter
    {
        public async Task<string> ConvertToHeicAsync(string sourceImagePath, int quality)
        {
            var sourceImage = UIImage.FromFile(sourceImagePath);
            if (sourceImage == null)
                throw new FileNotFoundException("源图片不存在");

            // 创建临时HEIC文件路径
            var tempHeicPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.heic");

            // 使用ImageIO框架写入HEIC格式并设置压缩质量
            using (var imageDestination = CGImageDestination.Create(tempHeicPath, "public.heic", 1, null))
            {
                var qualityProp = new NSDictionary(
                    CGImageDestinationProperties.Quality, (nfloat)(quality / 100.0f)
                );
                imageDestination.AddImage(sourceImage.CGImage, qualityProp);
                imageDestination.Close();
            }

            return tempHeicPath;
        }
    }
}

注:iOS 14+可直接使用sourceImage.AsHEIC((nfloat)(quality/100.0f))简化实现,以上写法兼容iOS 11+

3. Android平台实现(Android项目)

Android从API 28(Android 9.0)开始支持HEIF,使用ImageWriter实现格式转换:

[assembly: Dependency(typeof(ImageHeicConverter_Android))]
namespace YourAppNamespace.Droid
{
    public class ImageHeicConverter_Android : IImageHeicConverter
    {
        public async Task<string> ConvertToHeicAsync(string sourceImagePath, int quality)
        {
            if (Build.VERSION.SdkInt < BuildVersionCodes.P)
                throw new NotSupportedException("仅Android 9.0及以上版本支持HEIF格式");

            var sourceBitmap = BitmapFactory.DecodeFile(sourceImagePath);
            if (sourceBitmap == null)
                throw new FileNotFoundException("源图片不存在");

            // 创建临时HEIC文件
            var tempFile = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), 
                $"{Guid.NewGuid()}.heic");
            var tempHeicPath = tempFile.AbsolutePath;

            // 写入HEIF格式并设置压缩质量
            using var outputStream = new FileOutputStream(tempFile);
            using var imageWriter = ImageWriter.NewInstance(outputStream, ImageFormat.Heic, 1, null);
            var inputImage = imageWriter.GetInputImage();
            var buffer = inputImage.GetPlanes()[0].Buffer;
            
            sourceBitmap.CopyPixelsToBuffer(buffer);
            var encoderBundle = new Bundle();
            encoderBundle.PutInt(ImageEncoder.Quality, quality);
            imageWriter.SetEncoderProperties(encoderBundle);
            imageWriter.WriteImage();

            sourceBitmap.Recycle();
            return tempHeicPath;
        }
    }
}

4. 图片获取与转换流程

使用Xamarin.Essentials.MediaPicker替代Plugin.Media,直接获取原始图片路径后转换:

// 从相册选择图片
var pickResult = await MediaPicker.PickPhotoAsync(new MediaPickerOptions { Title = "选择图片" });
if (pickResult != null)
{
    // 转换为HEIC并压缩(质量设为70)
    var heicPath = await DependencyService.Get<IImageHeicConverter>().ConvertToHeicAsync(pickResult.FullPath, 70);
    // 上传heicPath对应的文件到服务器
}

// 拍照获取图片
var captureResult = await MediaPicker.CapturePhotoAsync();
if (captureResult != null)
{
    var heicPath = await DependencyService.Get<IImageHeicConverter>().ConvertToHeicAsync(captureResult.FullPath, 60);
    // 上传逻辑
}

5. 关键注意事项

  • 权限配置:iOS需在Info.plist添加NSCameraUsageDescription、NSPhotoLibraryUsageDescription;Android需在AndroidManifest.xml添加CAMERA、READ_EXTERNAL_STORAGE(Android 10+需ACCESS_MEDIA_LOCATION)权限。
  • 兼容性兜底:对不支持HEIC的Android低版本设备,可添加JPG格式的 fallback 转换逻辑。
  • 双重压缩:若需更小文件,可先按比例缩小图片分辨率,再进行HEIC格式压缩。

内容的提问来源于stack exchange,提问作者ramdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:01:20