首页
学习
活动
专区
工具
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.2K30

    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 剩余的类型信息移入元空间

    49300

    从 Linux 线程创建到 docker 的 namespace

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

    38130

    我用Builder优雅的实现了对象的创建

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

    73010
    领券