首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

从CIImage创建的UIImage创建的JPG太大了3倍

基础概念

CIImage 是 Core Image 框架中的一个类,用于表示图像数据。UIImage 是 UIKit 框架中的一个类,用于在 iOS 应用程序中显示和处理图像。将 CIImage 转换为 UIImage 并保存为 JPG 文件时,可能会遇到文件大小过大的问题。

问题原因

  1. 图像质量设置过高:默认情况下,保存 JPG 图像时可能会使用较高的质量设置,导致文件过大。
  2. 图像分辨率过高:如果原始 CIImage 的分辨率很高,保存为 JPG 文件时会占用更多空间。
  3. 色彩空间和位深度:不同的色彩空间和位深度也会影响图像文件的大小。

解决方法

可以通过调整图像质量和分辨率来减小 JPG 文件的大小。以下是一个示例代码,展示如何将 CIImage 转换为 UIImage 并保存为较小的 JPG 文件:

代码语言:txt
复制
import UIKit
import CoreImage

func saveCIImageAsJPG(_ ciImage: CIImage, quality: CGFloat = 0.75, completion: @escaping (URL?) -> Void) {
    let context = CIContext(options: nil)
    guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
        completion(nil)
        return
    }
    
    let image = UIImage(cgImage: cgImage)
    guard let data = image.jpegData(compressionQuality: quality) else {
        completion(nil)
        return
    }
    
    let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("image.jpg")
    do {
        try data.write(to: url)
        completion(url)
    } catch {
        completion(nil)
    }
}

// 示例调用
let ciImage = // 获取你的 CIImage 对象
saveCIImageAsJPG(ciImage, quality: 0.5) { url in
    if let url = url {
        print("JPG 文件保存成功: \(url)")
    } else {
        print("JPG 文件保存失败")
    }
}

代码解释

  1. 创建 CIContext:使用 CIContextCIImage 转换为 CGImage
  2. 创建 UIImage:使用 CGImage 创建 UIImage 对象。
  3. 调整图像质量:使用 UIImagejpegData(compressionQuality:) 方法设置图像质量,值范围为 0.0 到 1.0,数值越小,文件越小。
  4. 保存文件:将调整后的图像数据保存为 JPG 文件。

参考链接

通过调整图像质量和分辨率,可以有效减小 JPG 文件的大小,同时保持图像质量在可接受范围内。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Swift3.1动画之Core Image

CIImage。该类保存图像数据。它可以UIImage图像文件或像素数据创建。 CIFilter。CIFilter类有一个字典,用于定义它所代表特定过滤器属性。...事实证明,UIImage(ciImage:)code构造函数为您做所有的工作。它创建CIContext并使用它来执行过滤图像工作。...接下来,您使用UIImage(cgImage:)构造函数从新创建CGImage创建UIImage,而不是像以前一样直接CIImage创建。...在这个例子中,自己处理CIContext创建并没有太多区别。但在下一节中,您将看到为什么这对于性能很重要,因为您实现动态修改过滤器功能!...CIImages实际上并不包含图像数据,它们描述创建“配方”。直到你在CIContext上调用一个方法来实际处理数据。

1.5K80

swift手撕二维码一、简介二、二维码综合案例

二维码就像是神一般存在!! 可是到底二维码是个啥呢? QRCode.jpg 一、简介 1、概念 用某种特定几何图形按照一定规律在平面分布黑白相间图形记录数据符号信息。...实例化二维码滤镜 恢复滤镜默认属性 将字符串转换成NSData数据 通过KVC设置滤镜inputMessage数据 获得滤镜输出图像 将CIImage转换成UIImage,并放大显示 通过位图创建高清图片...若有值,将CIImage图片转换成UIImage类型图片。 if let image = filter?....回到touchsBegin方法中,创建需要嵌入到二维码中小图片,并用二维码图片调用封装好方法得到返回图片 let center = UIImage(named: "img_1.jpg") resultImage...接下来要为扫描线设置动画,创建一个类扩展自ScanQRCode,添加一个扫描方法。 在扫描时候,线是最上方往最下方开始扫描,因此底部约束最开始时候是停留在最上方。

1.8K70
  • iOS 中CIFilter(基础用法)

    我一度想查找API里一共提供多少种滤镜,每种滤镜分别有什么效果。可能是种类实在是太多,不同滤镜又有很多不同参数(参数名,参数各种都可能不同)设置,基本没有介绍每种滤镜文章。...可以用UIImage或者图片路径或者data来创建一个CIImage对象。...CIFilter.滤镜类,它有一个用来设置各种参数字典,API已经提供setValue: forKey:方法来设置参数。...将处理过后图片数据,输出为CIImage时候会用到CIContext。 创建一个滤镜. 创建好滤镜后,我们需要为其设置参数。有的滤镜要设置参数比较多,有的滤镜却不需要设置参数。...) // 4.将CIImage转换为UIImage // 其实在这个API内部用到了CIContext,而它就是在每次使用使用去创建一个新CIContext,比较影响性能 let newImage

    2.1K30

    ios 几种容易忽略内存泄漏方式

    一、AFNetWorking说起 对于AFNetWorking使用我们通常会对通用参数、网址环境切换、网络状态监测、请求错误信息等进行封装。...在封装网络请求类时需注意是需要将请求队列管理者AFHTTPSessionManager声明为单例创建形式,使用者在相同配置下保证AFHTTPSessionManager只有一个,进行全局管理,因此我们可以通过单例形式进行解决...举个例子,比如常用滤镜操作调节图片亮度 CIImage *beginImage = [[CIImage alloc]initWithImage:[UIImage imageNamed:@"yourname.jpg...*endImg = [UIImage imageWithCGImage:ref]; _imageView.image = endImg; CGImageRelease(ref);//非OC对象需要手动内存释放...,直至循环结束才释放,可能导致内存泄漏,解决方法为在循环中创建自己autoReleasePool,及时释放占用内存大临时变量,减少内存占用峰值。

    1.7K20

    创建 Java 对象搁哪

    关注我一起学习,悄悄超过他 拒绝做知识“收藏家” 答应我,跟我一起学习吧,别再做知识收藏家,把《深入理解 Java 虚拟机》书拿出来,翻它,盘它,磋磨它。 你创建 Java 对象搁哪 ?...(允许动态扩展由虚拟机实现方自行选择,hotspot选择则是不允许动态扩展) 不需要保证连续内存 方法执行时使用; 注:在 hotspot 中不允许扩展栈内存,但同样会发生 OOM ,这是发生在创建线程内存申请时内存不足抛出...容量超过允许最大值时抛出 OOM 异常(允许动态扩展) 不需要保证连续内存 虚拟机启动时创建 后被替换为元空间(这里内容要和 hotspot “永久代“一起理解,JDK7开始将永久代对象移除放入堆中...,静态变量以及常量) 运行时常量池 (这部分内存区域同在方法区中体现) 线程共享 存储接口或类常量池(字面量 与 符号引用类全部限定名等信息) 类加载时创建 类加载时创建过程使用方法区内存大小,可能出现...JDK4中 NIO 首次使用; 在设置JVM参数时,需考虑直接内存使用大小,防止其过渡使用出现 OOM; JDK7时候,使用直接内存实现方法区,到 JDK8 将 JDK 7 剩余类型信息移入元空间

    49000

    Linux 线程创建到 docker namespace

    Linux 早期是没有线程概念,因此他只设计进程结构体,Linux 上是怎么设计线程呢?...return 0;}这是glibc 2.39 源码,可以看到他设置 flag 然后调用 __clone_internal 函数,而他底层就是我们前边 clone 函数。...你可能会好奇,clone 不是子进程创建吗,为什么也可以创建线程,这个时候就是 clone_flags 作用了,我们看到线程创建传入了很多 flag ,而这就是进程创建和线程创建区别。...namespace所以为什么线程谈到 docker ,因为 docker namespace 就是依靠这几个标记实现进程隔离,使得 pid ipc 等产生隔离。...当然开发者角度来看就是,设计需求变更时候加个字段事情。

    37930

    我用Builder优雅实现对象创建

    使用构造函数直接属性赋值 Java对象创建大家都知道,当对象创建完之后,我们可以有几种方式给对象属性赋值。比如在new时候给属性赋值。像这样: 这样在创建对象时就将属性赋值,的确很方便。...但是如果对象属性很多,我们这么赋值就很不优雅。 使用setter属性赋值 一般我们实际开发中,实体类会有很多属性。...使用Builder属性赋值 其实我们可以使用Lombok@Builder注解,能够使我们更直观创建对象,同时给属性赋值。我们在实体类上面添加注解@Builder。...@Builder public class ProductInfo { ... } 然后创建对象时直接给属性赋值: 这样我们创建对象与给属性赋值就没有分开,提升了代码阅读性。...使用Builder创建对象,我们需要最终调用完build()方法对象才创建完成。保证对象完整性。

    72310
    领券