如何将 UIImage 转换为 CIImage,反之亦然
Posted
技术标签:
【中文标题】如何将 UIImage 转换为 CIImage,反之亦然【英文标题】:How to Convert UIImage to CIImage and vice versa 【发布时间】:2012-01-15 13:46:48 【问题描述】:我正在尝试从屏幕上显示的 ImageView 获取 CIImage
。
UIImage *image = myImageView.image;
将图像UIImage
转换为CIImage
。
CIImage *cImage = [....];
如何做到这一点?
【问题讨论】:
【参考方案1】:这是最兼容的方式:
UIImage* u =[UIImage imageNamed:@"image.png"];
CIImage* ciimage = [[CIImage alloc] initWithCGImage:u.CGImage];
现在使用 ciimage...
和 Swift 版本:
let i1 = UIImage(named: "testImage")
if let cgi1 = i1?.cgImage
let ci = CIImage(cgImage: cgi1)
//use ci
(修正了 if let 语句中的错字)
【讨论】:
要从 UIImage 创建 CIImage,使用 initWithCGImage 是唯一有效的解决方案。做 'uiimagei.CIImage 没有用,它总是为零。【参考方案2】:CIImage *ciImage = [UIImage imageNamed:@"test.png"].CIImage;
UIImage *uiImage = [[UIImage alloc] initWithCIImage:ciImage];
要解决 myUIImage.CIImage
像 [UIImageView image]
这样返回 nil
的情况,您可以改用 [CIImage imageWithCGImage:myUIImage.CGImage]
– Dylan Hand
Swift 版本:
let ciImage = UIImage(named: "test.png")!.ciImage
let uiImage = UIImage(ciImage: ciImage)
要解决myUIImage.ciImage
返回nil
的情况,您可以改为使用CIImage(cgImage: myUIImage!.cgImage!)
。
【讨论】:
不管怎样,总是会调用 alloc...[UIImage imageWithCIImage:ciImage]
相当于 [[[UIImage alloc] initWithCIImage:ciImage] autorelease]
小心点。如果 UIImage
用 CGImageRef
初始化,CIImage
将是 nil
,这将不起作用。
使用...WithCIImage:
创建的UIImage
在调整大小时确实存在一些问题,因为大多数带有UIImage
的框架都需要CGImage
。所以你需要先用createCGImage:fromRect:
或类似的东西来渲染它。
要解决myUIImage.CIImage
返回nil
的情况,您可以改为使用[CIImage imageWithCGImage:myUIImage.CGImage]
。
如果可能,最好使用 imageWithCIImage:scale:orientation 而不是 imageWithCIImage CIImage* aCIImage = [CIImage imageWithData:imageData]; UIImage* anImage = [UIImage imageWithCIImage:aCIImage scale:1.0orientation:orientation];【参考方案3】:
在将 UIImage 转换为 CIImage 时,我遇到了两种不同的情况,有时它是零,有时不是。下面的代码解决了它:
CIImage *ciImage;
ciImage=[[CIImage alloc] initWithImage:imageToConvert];
if (ciImage==nil)
ciImage=imageToConvert.CIImage;
【讨论】:
【参考方案4】:斯威夫特 3/4
UIImage > CIImage
let ciimage = CIImage(image: image)
https://developer.apple.com/documentation/uikit/uiimage/1624090-init
CIImage > UIImage
let image = UIImage(ciImage: ciimage)
https://developer.apple.com/documentation/coreimage/ciimage/1624119-init
【讨论】:
【参考方案5】:changx 答案的 Swift 示例:
guard let ciimage = CIImage(image: uiimage) else return
let image = UIImage(CIImage: ciimage)
【讨论】:
它不转换任何东西,如果不是从 ciimage 构造的,将返回nil
你不需要上下文吗?【参考方案6】:
func toCIImage(image: UIImage) -> CIImage
return image.CIImage ?? CIImage(CGImage: image.CGImage!)
func toUIImage(image: CIImage) -> UIImage
return UIImage(CIImage: image)
【讨论】:
它不转换任何东西,如果不是从 ciimage 构造,将返回nil
【参考方案7】:
这是我在项目中使用的完整代码示例。
- (UIImage *)makeUIImageFromCIImage:(CIImage *)ciImage
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:ciImage fromRect:[ciImage extent]];
UIImage* uiImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return uiImage;
CIImage
基本上是图像的配方。如果您尝试直接从CIImage
转换为UIImage
,将会遇到问题。比如调用
NSData * UIImageJPEGRepresentation (
UIImage *image,
CGFloat compressionQuality
);
将返回nil
。
【讨论】:
【参考方案8】:虽然 Changxing Wang 的回答实际上是正确的,但 Apple 表示 UIImage.CIImage 并不总是有效。具体来说,来自 PocketCoreImage:
// Create a CIImage from the _inputImage. While UIImage has a property returning
// a CIImage representation of it, there are cases where it will not work. This is the
// most compatible route.
_filteredImage = [[CIImage alloc] initWithCGImage:_inputImage.CGImage options:nil];
Apple 还使用以下内容,但对我不起作用:
[UIImage imageWithCIImage:_filteredImage]
我个人的实现,改编自 this post 对我有用:
// result is a CIImage, output of my filtering.
// returnImage is (obviously) a UIImage that I'm going to return.
CIContext *context = [CIContext contextWithOptions:nil];
UIImage *returnImage =
[UIImage imageWithCGImage:[context createCGImage:result fromRect:result.extent]];
【讨论】:
在设置上下文时要小心,除非您绝对必须这样做,因为这通常是一项昂贵的任务。我建议设置为@property 并在处理图像转换之前创建它。但是,如果您只这样做一次,上述解决方案应该可以正常工作。 创建的 CGImageRef 将被保留。您必须保持对它的引用,并在创建 UIImage 后调用 CGImageRelease(cgimage)。否则内存会泄露 您的代码泄漏:[context createCGImage...] 创建了一个必须释放的 CGContextRef(即使在 ARC 中)。因为你没有把它赋值给一个变量,所以你不能释放它,而且你在这里泄漏了相当多的内存。以上是关于如何将 UIImage 转换为 CIImage,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章
UIImage 在将其转换为 CIImage,然后转换为 CGImage 并返回 UIImage 时失去其方向
Objective c 在转换为 UIImage 时丢失了 CIImage 内存
在 iOS 7 之前的项目中编译警告“不兼容的指针类型初始化 'UIImage *' 使用类型为'CIImage * _Nullable”的表达式