Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.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 图像质量_Ios_Swift_Uiimage - Fatal编程技术网

Ios 图像质量

Ios 图像质量,ios,swift,uiimage,Ios,Swift,Uiimage,我正在使用此功能调整各种图像的大小: func resizeImage(image: UIImage) -> UIImage { var actualHeight: CGFloat = image.size.height var actualWidth: CGFloat = image.size.width let maxHeight: CGFloat = 600.0 let maxWidth: CGFloat =

我正在使用此功能调整各种图像的大小:

    func resizeImage(image: UIImage) -> UIImage {
        var actualHeight: CGFloat = image.size.height
        var actualWidth: CGFloat = image.size.width

        let maxHeight: CGFloat = 600.0
        let maxWidth: CGFloat = text.frame.size.width - 10

        var imgRatio: CGFloat = actualWidth / actualHeight
        let maxRatio: CGFloat = maxWidth / maxHeight
        let compressionQuality: CGFloat = 0.5
        //50 percent compression
        if actualHeight > maxHeight || actualWidth > maxWidth {
            if imgRatio < maxRatio {
                //adjust width according to maxHeight
                imgRatio = maxHeight / actualHeight
                actualWidth = imgRatio * actualWidth
                actualHeight = maxHeight
            }
            else if imgRatio > maxRatio {
                //adjust height according to maxWidth
                imgRatio = maxWidth / actualWidth
                actualHeight = imgRatio * actualHeight
                actualWidth = maxWidth
            }
            else {
                actualHeight = maxHeight
                actualWidth = maxWidth
            }
        }
        let rect: CGRect = CGRectMake(0.0, 0.0, actualWidth, actualHeight)
        UIGraphicsBeginImageContext(rect.size)
        image.drawInRect(rect)
        let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        let imageData: NSData = UIImageJPEGRepresentation(img, compressionQuality)!
        UIGraphicsEndImageContext()

        return UIImage(data: imageData)!
    }
func resizeImage(图像:UIImage)->UIImage{
变量实际高度:CGFloat=image.size.height
var actualWidth:CGFloat=image.size.width
设maxHeight:CGFloat=600.0
设maxWidth:CGFloat=text.frame.size.width-10
变量imgRatio:CGFloat=实际宽度/实际高度
设maxRatio:CGFloat=maxWidth/maxHeight
let压缩质量:CGFloat=0.5
//50%压缩
如果实际高度>最大高度| |实际宽度>最大宽度{
如果imgRatiomaxRatio{
//根据maxWidth调整高度
imgRatio=最大宽度/实际宽度
实际高度=绝对高度*实际高度
实际宽度=最大宽度
}
否则{
实际高度=最大高度
实际宽度=最大宽度
}
}
设rect:CGRect=CGRectMake(0.0,0.0,实际宽度,实际高度)
UIGraphicsBeginImageContext(矩形大小)
image.drawInRect(rect)
让img:UIImage=UIGraphicsGetImageFromCurrentImageContext()
让imageData:NSData=UIImageJPEG表示(img,压缩质量)!
UIGraphicsSendImageContext()
返回UIImage(数据:imageData)!
}
但质量太差了……下面是我得到的照片:

我认为图像的质量取决于什么是压缩质量。。。?从上面的代码中可以看出,我现在是0.5,但即使我将其更改为1,质量仍然很糟糕

任何想法


非常感谢。

您应该改用
UIGraphicsBeginImageContextWithOptions(rect.size,false,0.0)
。它将为您的设备使用正确的刻度。您正在使用的版本(无选项)使用默认比例因子
1.0
。使用
…WithOptions()
变量并传入
0.0
作为刻度,默认为设备的本机刻度。请注意,这可能不是您想要的

其次,您可以使用
AVMakeRectWithAspectRatioInsideRect()
计算目标大小。第三,您不需要经过JPEG编码,您可以直接返回生成的图像

结合起来,这将大大简化您的代码:

func resizeImage(image: UIImage) -> UIImage {
  let maxSize = CGSize(
    width: text.frame.size.width - 10, 
    height: 600.0
  )
  let newSize = AVMakeRectWithAspectRatioInsideRect(
    image.size, 
    CGRect(origin: CGPointZero, size: maxSize)
  ).size
  UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
  image.drawInRect(CGRect(origin: CGPointZero, size: newSize))
  let scaled = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
  return scaled
}
编辑:这是我在项目中使用的
UIImage
的扩展:

extension UIImage {
    /**
     Returns an scaled version of self that fits within the provided bounding box.
     It retains aspect ratio, and also retains the rendering mode.
     - parameter size: The target size, in point
     - parameter scale: Optional target scale. If omitted, uses the scale of input image
     - returns: A scaled image
     */
    func imageFittingSize(size: CGSize, scale: CGFloat? = nil) -> UIImage {
        let newSize = AVMakeRectWithAspectRatioInsideRect(self.size, CGRect(origin: CGPointZero, size: size)).size
        UIGraphicsBeginImageContextWithOptions(newSize, false, scale ?? self.scale)
        self.drawInRect(CGRect(origin: CGPointZero, size: newSize))
        let scaled = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaled.imageWithRenderingMode(renderingMode)
    }
}
您可以在这样的图像上调用它:

let maxSize = CGSize(width: text.frame.size.width - 10, height: 600.0)
let scaled = image.imageFittingSize(maxSize)

您应该使用
UIGraphicsBeginImageContextWithOptions(rect.size,false,0.0)
。它将为您的设备使用正确的刻度。您正在使用的版本(无选项)使用默认比例因子
1.0
。使用
…WithOptions()
变量并传入
0.0
作为刻度,默认为设备的本机刻度。请注意,这可能不是您想要的

其次,您可以使用
AVMakeRectWithAspectRatioInsideRect()
计算目标大小。第三,您不需要经过JPEG编码,您可以直接返回生成的图像

结合起来,这将大大简化您的代码:

func resizeImage(image: UIImage) -> UIImage {
  let maxSize = CGSize(
    width: text.frame.size.width - 10, 
    height: 600.0
  )
  let newSize = AVMakeRectWithAspectRatioInsideRect(
    image.size, 
    CGRect(origin: CGPointZero, size: maxSize)
  ).size
  UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
  image.drawInRect(CGRect(origin: CGPointZero, size: newSize))
  let scaled = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
  return scaled
}
编辑:这是我在项目中使用的
UIImage
的扩展:

extension UIImage {
    /**
     Returns an scaled version of self that fits within the provided bounding box.
     It retains aspect ratio, and also retains the rendering mode.
     - parameter size: The target size, in point
     - parameter scale: Optional target scale. If omitted, uses the scale of input image
     - returns: A scaled image
     */
    func imageFittingSize(size: CGSize, scale: CGFloat? = nil) -> UIImage {
        let newSize = AVMakeRectWithAspectRatioInsideRect(self.size, CGRect(origin: CGPointZero, size: size)).size
        UIGraphicsBeginImageContextWithOptions(newSize, false, scale ?? self.scale)
        self.drawInRect(CGRect(origin: CGPointZero, size: newSize))
        let scaled = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaled.imageWithRenderingMode(renderingMode)
    }
}
您可以在这样的图像上调用它:

let maxSize = CGSize(width: text.frame.size.width - 10, height: 600.0)
let scaled = image.imageFittingSize(maxSize)

0.5的压缩比是否适合原始大小似乎是一种模糊效果?@zcui93不确定我是否理解您的意思您的代码似乎还可以。你能在问题中添加同一图像的原始和修改版本吗?0.5压缩比以适应原始大小似乎是一种模糊效果?@zcui93不确定我是否理解你的意思你的代码似乎还可以。你能将同一图像的原始版本和修改版本添加到问题中吗?嗨,谢谢,我猜我需要安装AVFoundation framework?不,它包含在iOS SDK中,但你需要在文件顶部导入它。质量看起来不错,但大小不对……是的,AVFoundation函数创建一个以目标边界为中心的rect。很抱歉我已经更新了答案。1.6分的分数似乎不合理。这意味着像素大小在两个方向上都是图像点大小的1.6倍。在视网膜设备上,它有效地去除了大约一半的像素,从而使文件大小大约减半。然而,你也得到了一半的像素,因此设备将对其重新采样以正确显示。在任何一个方向上,大约每隔一个图像像素就会被拉伸到两个显示设备像素上。它可能对您有用,但这是一个黑客。您好,谢谢,我猜我需要安装AVFoundation framework?不,它包含在iOS SDK中,但您需要在文件顶部导入它。质量看起来不错,但大小不合适……是的,AVFoundation函数创建了一个以目标边界为中心的rect。很抱歉我已经更新了答案。1.6分的分数似乎不合理。这意味着像素大小在两个方向上都是图像点大小的1.6倍。在视网膜设备上,它有效地去除了大约一半的像素,从而使文件大小大约减半。然而,你也得到了一半的像素,因此设备将对其重新采样以正确显示。在任何一个方向上,大约每隔一个图像像素就会被拉伸到两个显示设备像素上。它可能对你有用,但这是一个黑客。