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

SwiftUI+Alamofire上传前将图片按比例缩至最大宽度1280px

SwiftUI + Alamofire 上传前图片缩放完整流程

1. 优化图片缩放函数

你提供的缩放函数可以做两处优化:一是跳过无需缩放的小图,二是适配Retina屏幕避免图片模糊,修改后代码如下:

func resizeImage(image: UIImage, maxWidth: CGFloat) -> UIImage? {
    // 原图宽度小于等于目标宽度时直接返回,无需缩放
    guard image.size.width > maxWidth else { return image }
    
    let oldWidth = image.size.width
    let oldHeight = image.size.height
    
    let scaleFactor = maxWidth / oldWidth
    let newHeight = oldHeight * scaleFactor
    let newSize = CGSize(width: maxWidth, height: newHeight)
    
    // 用带屏幕scale的上下文生成清晰图片
    UIGraphicsBeginImageContextWithOptions(newSize, false, UIScreen.main.scale)
    image.draw(in: CGRect(origin: .zero, size: newSize))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return newImage
}

2. 在SwiftUI中获取待上传图片

通过图片选择器(通常用UIViewControllerRepresentable封装原生UIImagePickerController)选中图片后,拿到UIImage实例:

// 图片选择器回调示例
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    picker.dismiss(animated: true)
    guard let selectedImage = info[.originalImage] as? UIImage else { return }
    
    // 后台线程执行缩放,避免阻塞UI
    DispatchQueue.global().async {
        if let resizedImage = self.resizeImage(image: selectedImage, maxWidth: 1280) {
            DispatchQueue.main.async {
                self.uploadResizedImage(resizedImage)
            }
        }
    }
}

3. 缩放后图片转Data并通过Alamofire上传

将缩放后的UIImage转为JPEG/PNG格式的Data,再用Alamofire的多表单上传接口提交:

func uploadResizedImage(_ image: UIImage) {
    // 转JPEG格式(压缩质量0.8平衡体积与清晰度,可按需调整)
    guard let imageData = image.jpegData(compressionQuality: 0.8) else {
        print("图片转Data失败")
        return
    }
    
    // Alamofire上传逻辑
    AF.upload(multipartFormData: { multipartFormData in
        // 按服务器要求设置参数名、文件名、MIME类型
        multipartFormData.append(imageData, 
                                 withName: "uploaded_image", 
                                 fileName: "resized_image.jpg", 
                                 mimeType: "image/jpeg")
        // 如有其他参数,在此添加
        // multipartFormData.append("user_token".data(using: .utf8)!, withName: "token")
    }, to: "你的服务器上传接口URL")
    .responseJSON { response in
        switch response.result {
        case .success(let result):
            print("上传成功:\(result)")
        case .failure(let error):
            print("上传失败:\(error.localizedDescription)")
        }
    }
}

关键注意事项

  • 权限配置:在Info.plist中添加NSPhotoLibraryUsageDescription,申请相册访问权限,否则无法选择图片。
  • 线程处理:图片缩放和转Data属于耗时操作,必须放在后台线程执行,完成后切回主线程处理上传或UI更新。
  • 压缩质量:jpegData(compressionQuality:)的参数范围是0-1,数值越高质量越好但体积越大,建议根据服务器要求调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 08:00:06