缩小 UIImage 并保持清晰
Scaling down UIImage and keep it sharp
我正在使用 this 问题的答案来缩小图像并使其不模糊。但是,这对我不起作用。我正在使用 Swift。我做的一切都像答案一样。这是我使用的函数的代码:
func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
let newRect = CGRectIntegral(CGRectMake(0,0, newSize.width, newSize.height))
let imageRef = image.CGImage
UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
let context = UIGraphicsGetCurrentContext()
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(context, CGInterpolationQuality.High)
let flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height)
CGContextConcatCTM(context, flipVertical)
// Draw into the context; this scales the image
CGContextDrawImage(context, newRect, imageRef)
let newImageRef = CGBitmapContextCreateImage(context)! as CGImage
let newImage = UIImage(CGImage: newImageRef)
// Get the resized image from the context and a UIImage
UIGraphicsEndImageContext()
return newImage
}
我就是这样称呼它的:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "mypin"
if annotation.isKindOfClass(MKUserLocation) {
return nil
}
let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure)
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil
{
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin")
annotationView!.canShowCallout = true
let pinImage = UIImage(named: "Pin.png")
let resizedImage = resizeImage(pinImage!, newSize: CGSize(width: 12, height: 20))
annotationView?.image = resizedImage
annotationView!.rightCalloutAccessoryView = detailButton
}
else
{
annotationView!.annotation = annotation
}
return annotationView
}
如果有人知道为什么会发生这种情况,请告诉我,我将不胜感激。
提前致谢。
这样好点了吗?是的,它跳过了很多,但对于我的注释,它工作正常。
func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
let scale: CGFloat = 0.0 //whatever
UIGraphicsBeginImageContextWithOptions(newSize, true, scale)
image.drawInRect(CGRect(origin: CGPointZero, size: newSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
正如我在评论中所怀疑的那样,这是因为 CGBitmapContextCreateImage
会忽略您输入 UIGraphicsBeginImageContextWithOptions
的比例——而是始终创建比例为 [=12 的图像=].
例如,如果您有 3 倍比例的 50 x 50 图像上下文:
CGBitmapContextCreateImage
将 return 1x 比例的 150 x 150 图像
UIGraphicsGetImageFromCurrentImageContext
将 return 3 倍比例的 50 x 50 图像
通常这在屏幕上显示图像时实际上应该没有什么区别,除非您依赖以点而不是像素指定的大小。但是,对于 MKAnnotationView
、the documentation says:
Assigning a new image to this property also changes the size of the view’s frame so that it matches the width and height of the new image.
因此,如果您为它分配一个 1 倍比例的图像(并且您的屏幕比例高于 1 倍)——它会被不必要地放大,从而降低质量。因此,解决方法是使用 UIGraphicsGetImageFromCurrentImageContext
.
我正在使用 this 问题的答案来缩小图像并使其不模糊。但是,这对我不起作用。我正在使用 Swift。我做的一切都像答案一样。这是我使用的函数的代码:
func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
let newRect = CGRectIntegral(CGRectMake(0,0, newSize.width, newSize.height))
let imageRef = image.CGImage
UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
let context = UIGraphicsGetCurrentContext()
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(context, CGInterpolationQuality.High)
let flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height)
CGContextConcatCTM(context, flipVertical)
// Draw into the context; this scales the image
CGContextDrawImage(context, newRect, imageRef)
let newImageRef = CGBitmapContextCreateImage(context)! as CGImage
let newImage = UIImage(CGImage: newImageRef)
// Get the resized image from the context and a UIImage
UIGraphicsEndImageContext()
return newImage
}
我就是这样称呼它的:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "mypin"
if annotation.isKindOfClass(MKUserLocation) {
return nil
}
let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure)
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil
{
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin")
annotationView!.canShowCallout = true
let pinImage = UIImage(named: "Pin.png")
let resizedImage = resizeImage(pinImage!, newSize: CGSize(width: 12, height: 20))
annotationView?.image = resizedImage
annotationView!.rightCalloutAccessoryView = detailButton
}
else
{
annotationView!.annotation = annotation
}
return annotationView
}
如果有人知道为什么会发生这种情况,请告诉我,我将不胜感激。 提前致谢。
这样好点了吗?是的,它跳过了很多,但对于我的注释,它工作正常。
func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
let scale: CGFloat = 0.0 //whatever
UIGraphicsBeginImageContextWithOptions(newSize, true, scale)
image.drawInRect(CGRect(origin: CGPointZero, size: newSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
正如我在评论中所怀疑的那样,这是因为 CGBitmapContextCreateImage
会忽略您输入 UIGraphicsBeginImageContextWithOptions
的比例——而是始终创建比例为 [=12 的图像=].
例如,如果您有 3 倍比例的 50 x 50 图像上下文:
CGBitmapContextCreateImage
将 return 1x 比例的 150 x 150 图像UIGraphicsGetImageFromCurrentImageContext
将 return 3 倍比例的 50 x 50 图像
通常这在屏幕上显示图像时实际上应该没有什么区别,除非您依赖以点而不是像素指定的大小。但是,对于 MKAnnotationView
、the documentation says:
Assigning a new image to this property also changes the size of the view’s frame so that it matches the width and height of the new image.
因此,如果您为它分配一个 1 倍比例的图像(并且您的屏幕比例高于 1 倍)——它会被不必要地放大,从而降低质量。因此,解决方法是使用 UIGraphicsGetImageFromCurrentImageContext
.