【问题标题】:UIImage in UIButton pixelated with Vector ImageUIButton 中的 UIImage 用矢量图像像素化
【发布时间】:2016-08-22 04:51:50
【问题描述】:

我正在尝试使用 Swift 在 XCode 中的 UIButton 中放入图像。该按钮位于键盘扩展中,我正在尝试放入“地球”图标,就像 iOS 内置键盘中已有的一样。我曾经使用地球 emoji 和 unicode(它会自动被选为 emoji),但这看起来不太好。

所以现在,无论我使用哪个文件,我的图像都是模糊的。到目前为止,我使用了 22pt、200pt、600pt、svg 和 pdf 的图像。没有运气。

这是它的样子: Blurry image

这就是 Apple 的外观,十分锐利:Sharp image

我的按钮代码是这样的:

//Set an image to fit inside a button
    let btn = nextKeyboardButton
    let image = UIImage(named: "globe")!
    var scaledImage = image
    var targetWidth : CGFloat = 0
    var targetHeight : CGFloat = 0
    let spacing : CGFloat = 10

    if(btn.frame.width < btn.frame.height){
        targetWidth = round(btn.frame.width - (spacing * 2))
        targetHeight = targetWidth
    } else {
        targetHeight = round(btn.frame.height - (spacing * 2))
        targetWidth = targetHeight
    }

    UIGraphicsBeginImageContext(CGSizeMake(targetWidth, targetHeight))
    image.drawInRect(CGRectMake(0, 0, targetWidth, targetHeight))
    scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    btn.setImage(scaledImage, forState: .Normal)
    btn.setTitle("", forState: .Normal)
    btn.tintColor = UIColor.blackColor()

由于图标是 1:1,我使用相同的宽度和高度。但是对于另一个图标/图像,我也需要相同的(工作)方法。我在 25、50 和 75pts 中为标签栏使用的任何其他图标/图像看起来都很好且清晰。我使用哪个模拟器也没关系,如果是 iPhone 4s 或 6 Plus。

另外,还有其他解决方案吗?我尝试使用另一种全是地球仪的字体,但 XCode 不会在编辑器中列出它。我也尝试过在全球范围内绘制表情符号,使用 unicode 字符,但它会被当作表情符号......所以.. 有什么帮助吗? :)

【问题讨论】:

  • 我知道这听起来很琐碎,但是您是否以@2x 和@3x 结束了较大图像的名称?另外,您是否尝试过使用PNG?我通常使用它,它看起来很完美。您是否也尝试过以像素而不是点来保存图像?
  • 有两个问题: 1. 资产文件中的矢量图像在构建时转换为 PNG 文件,因此在缩放时保证会出现一些模糊(与 PDF 是本机渲染的情况相反),以及2.UIGraphicsBeginImageContext不使用设备缩放。你想要UIGraphicsBeginImageContextWithOptions(size, NO, 0)
  • 是的,我尝试了很多东西,因此记得把 2x 和 3x 正确。我什至考虑让它们变成不同的颜色,只是为了看看使用的是哪一种。我也尝试过像素和点。但我确实怀疑 UIGraphicsBeginImageContext 是这里的问题。我只是不太熟悉它。我会试一下! :)

标签: ios swift uibutton uiimage


【解决方案1】:

对于可能正在寻找类似问题的解决方案或为按钮添加图像的任何感兴趣的人,我已经制作了一个完整的功能来执行此操作,并提供了来自@Brian Nickel 的建议修复/帮助:)

该函数只需要一个按钮、图像名称、颜色和图像周围缩进的间距。

func setImageForButton(_button : UIButton, _color : UIColor, _imageName : String, _spacing : CGFloat) {
    let btn = _button

    let image = UIImage(named: _imageName)!
    var scaledImage : UIImage

    var targetWidth : CGFloat
    var targetHeight : CGFloat
    let spacing : CGFloat = _spacing

    if(btn.frame.width < btn.frame.height){
        targetWidth = btn.frame.width - (spacing * 2)
        let scale = targetWidth / image.size.width
        targetHeight = round(image.size.height * scale)
        targetWidth = round(targetWidth)
    } else {
        targetHeight = btn.frame.height - (spacing * 2)
        let scale = targetHeight / image.size.height
        targetWidth = round(image.size.width * scale)
        targetHeight = round(targetHeight)
    }

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(targetWidth, targetHeight), false, 0)
    image.drawInRect(CGRectMake(0, 0, targetWidth, targetHeight))
    scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    btn.setImage(scaledImage, forState: .Normal)
    btn.setTitle("", forState: .Normal)
    btn.tintColor = _color
}

【讨论】:

    【解决方案2】:

    您的主要问题是UIGraphicsBeginImageContext 不执行特定于设备的缩放。在@2x 屏幕上,每个点都由一个像素表示,而不是一个 2x2 像素的正方形;它看起来像像素化,因为它是。

    切换到UIGraphicsBeginImageContextWithOptions(size, NO, 0) 并提供足够大的值应该会使其呈现清晰。

    另一个需要注意的问题是,PDF 资源在构建时而不是在应用程序中呈现为 PNG 文件的多种分辨率,因此如果将 22x22 图像呈现为 20x20(例如)会导致某种程度的模糊你不会想到矢量图像会在设备上呈现。

    【讨论】:

    • 这很有意义!我刚刚试了一下,效果很好!不过有一件事.. 那么哪种格式最好呢?比如说 25、50 和 75 的 PNG 文件,还是 PDF 或 22pts?我在某处读到 Apple 建议将 22pt 用于 PDF 文件的图标。
    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 2021-02-10
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多