Ios UIImage在将其转换为CIImage,然后转换为CGImage,再转换回UIImage时会松开其方向
我知道有很多这样的问题,但他们的解决方案对我来说并不适用 注意:图像是从Internet下载的。它不是从iPhone的摄像头拍摄的 我有一个Ios UIImage在将其转换为CIImage,然后转换为CGImage,再转换回UIImage时会松开其方向,ios,swift,uiimage,cgimage,ciimage,Ios,Swift,Uiimage,Cgimage,Ciimage,我知道有很多这样的问题,但他们的解决方案对我来说并不适用 注意:图像是从Internet下载的。它不是从iPhone的摄像头拍摄的 我有一个UIImage。要执行一些图像处理操作,我使用Metal,并在MTKView中显示图像。因此,我将图像转换为CIImage。 对图像进行所有修改后,我将其转换回CGImage,然后转换成UIImage,并保存它 因此,保存的图像的方向是错误的 我不确定它在哪一步松开了方向(当从UIImage转换为CIImage以添加到MTKView时,或者当从CIImage
UIImage
。要执行一些图像处理操作,我使用Metal
,并在MTKView
中显示图像。因此,我将图像转换为CIImage
。
对图像进行所有修改后,我将其转换回CGImage
,然后转换成UIImage
,并保存它
因此,保存的图像的方向是错误的
我不确定它在哪一步松开了方向(当从UIImage
转换为CIImage
以添加到MTKView
时,或者当从CIImage
转换为CGImage
然后转换为UIImage
以保存它时)。因为我不确定,贝娄我提供了我在每个步骤中尝试过的一切:
用于从UIImage
转换为CIImage
:
最初,我只是以这种方式转换图像:
let let ciImage = CIImage(image: image)
let imageToSave = UIImage(cgImage: cgImage, scale: image.scale, orientation: imageOrientation)
然后我尝试使用以下方法:
let ciImage = CIImage(image: image)?.oriented(forExifOrientation: imageOrientationToTiffOrientation(value: image.imageOrientation))
下面是方法ImageOrientationTiffOrientation
的实现(我找到了它):
用于从CIImage
转换为CGImage
,然后转换为UIImage
:
我像往常一样将CIImage
转换为CGImage
:
let cgImage = context?.createCGImage(ciImage, from: ciImage.extent)
然后我将cgImage
转换为UIImage
(imageToSave
):
let let ciImage = CIImage(image: image)
let imageToSave = UIImage(cgImage: cgImage, scale: image.scale, orientation: imageOrientation)
imageOrientation
和image.scale
是原始图像的方向和比例
结果,保存的图像仍然具有错误的方向
有趣的是,当我打印这些图像方向原始值时,它们是相同的0
,这是.up
,但是正如我所说的,保存后,方向是错误的
我很困惑为什么会这样。如果您对如何修复此问题有任何建议,我将非常感谢您的帮助。您可以尝试此方法
func image(with image: UIImage?, scaledToSizeKeepingAspect newSize: CGSize) -> UIImage? {
var newSize = newSize
var imgHeight = Float(image?.size.height ?? 0.0)
var imgWeight = Float(image?.size.width ?? 0.0)
var fact: Float = 0.0
if imgHeight > imgWeight {
fact = Float(CGFloat(imgHeight) / newSize.width)
} else {
fact = Float(CGFloat(imgWeight) / newSize.height)
}
imgHeight = imgHeight / fact
imgWeight = imgWeight / fact
newSize = CGSize(width: CGFloat(imgWeight), height: CGFloat(imgHeight))
UIGraphicsBeginImageContext(newSize)
// Tell the old image to draw in this new context, with the desired
// new size
image?.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
// Get the new image from the context
let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
// End the context
UIGraphicsEndImageContext()
// Return the new image.
return newImage
}
调用如下方法:
图像(带图像:图像,缩放的主题保留方面:图像.大小)
这里的图像是UIImage对象,您要在此方法中更改该图像的过程 创建CIImage时,从原始UIImage获取方向的方法是:
let ciImage = CIImage(image: image, options: [.applyOrientationProperty:true])!
完成CIImage后,使用CIContext()将数据保存到磁盘。writeJPEGRepresentation
将保留方向元数据。TLDR:
let uiImage: UIImage = ...
let ciImage = CIImage(image: uiImage, options:
[.applyOrientationProperty: true,
.properties: [kCGImagePropertyOrientation: CGImagePropertyOrientation(uiImage.imageOrientation).rawValue]])
要将UIImageOrientation
转换为CGImagePropertyOrientation
,此代码使用
长版本:
let uiImage: UIImage = ...
let ciImage = CIImage(image: uiImage, options:
[.applyOrientationProperty: true,
.properties: [kCGImagePropertyOrientation: CGImagePropertyOrientation(uiImage.imageOrientation).rawValue]])
我只是有类似的问题。将UIImage转换为CIImage时,图像可能出现错误方向:
let uiImage: UIImage = ...
let ciImage CIImage(image: uiImage) /* does not use uiImage orientation */
let ciImage = CIImage(image: uiImage)?.oriented(CGImagePropertyOrientation(uiImage.imageOrientation))
/* uses CGImagePropertyOrientation extension (see above) */
最简单的解决方案是使用oriented(:)
方法更改方向:
let uiImage: UIImage = ...
let ciImage CIImage(image: uiImage) /* does not use uiImage orientation */
let ciImage = CIImage(image: uiImage)?.oriented(CGImagePropertyOrientation(uiImage.imageOrientation))
/* uses CGImagePropertyOrientation extension (see above) */
这可能没问题,但面向(:)的方法会创建一个新图像。我认为一定有一种方法可以创建正确定向的CIImage
,而无需中间对象。还有!虽然我在互联网上的任何地方都找不到它,而且苹果也没有足够清晰的记录,所以我把它贴在这里@马特朝着正确的方向迈出了一步,但这还不够
解决方案在applyOrientationProperty
description中“加密”
图像可以包含在捕获时显示方向的元数据您可以加载
将元数据转换为CIImage,并使用imageWithContentsOfURL:或init(数据:)
当捕获的图像包含方向元数据时。使用任何
initWith:options:properties(NSDictionary)中的方法
属性)选项也提供了
重点强调了重要部分。那是一把钥匙。
同样重要的是不要混淆
选项
和属性
) 请出示你的实际代码,并解释你是如何“知道”你已经失去方向的。没有“保存”UIImage这样的事情,所以不清楚您在做什么。您只能保存图像数据。如果您的目标是保存CIImage中的图像数据,则应调用CIContext().writeJPEGRepresentation
。已尝试但未成功。我已经用CMSampleBuffer制作了一个CIIMage。我想在上面放置另一个图像(类似于标签),所以使用了CIImage中的合成(over:)方法。但是这个方向对贴纸不合适。@nr5我建议你作为一个新问题正式地问这个问题。也许有人能帮上忙。我试过:@nr5就我所知,那里没有关于方向的内容。