Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIImage在将其转换为CIImage,然后转换为CGImage,再转换回UIImage时会松开其方向_Ios_Swift_Uiimage_Cgimage_Ciimage - Fatal编程技术网

Ios UIImage在将其转换为CIImage,然后转换为CGImage,再转换回UIImage时会松开其方向

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

我知道有很多这样的问题,但他们的解决方案对我来说并不适用

注意:图像是从Internet下载的。它不是从iPhone的摄像头拍摄的

我有一个
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就我所知,那里没有关于方向的内容。