Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resizing an SKSpriteNode without losing quality

I have an SKSpiteNode:

private var btnSound = SKSpriteNode(imageNamed: "btnSound")

Now I made this image in Adobe Illustrator with a size of 2048x2048 pixels (overkill really), so it has good resolution. My problem is when I set the size of it the image, the lines in it go serrated or jagged...not smooth.

This is how I size it:

        btnSound.position = CGPoint(x: self.frame.width * 1 / 5 , y: self.frame.height * (5.2 / 8))
        btnSound.size.width = self.frame.width * 1 / 7
        btnSound.size.height = btnSound.size.width
        btnSound.zPosition = 1
        self.addChild(btnSound)

This is the image when in Illustrator (screenshot)imageand this is the image in the app (screenshot) image

Things I have tried:

  • Making the image PDF
  • Making the image PNG
  • Making the PNG 72 DPI, making it 300 DPI
  • Run on simulator / device (iPhone7)
  • btnSound.setScale(preDetermineScale)
  • Using the following function, though I am not familiar with the UIGraphicsBeginImageContext method. The image just comes out blurry with this. Heres the code and the resulting image:

    func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? {
    
    let scale = newWidth / image.size.width
    let newHeight = image.size.height * scale
    UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
    image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
    
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return newImage
    }
    
    func setup() {
    let btnSoundImg = UIImage(named: "btnSound")
    let resizeBtnSoundImage = resizeImage(image: btnSoundImg!, newWidth: self.frame.width * 1 / 7)
    let btnSoundTexture = SKTexture(image: resizeBtnSoundImage!)
    
    btnSound.texture = btnSoundTexture
    btnSound.position = CGPoint(x: self.frame.width * 1 / 5 , y: self.frame.height * (5.2 / 8))
    btnSound.size.width = self.frame.width * 1 / 7
    btnSound.size.height = btnSound.size.width
    btnSound.zPosition = 1
    self.addChild(btnSound)
    }
    

blurry image

I am self taught and haven't done a whole lot of programming so I'd love to learn how to do this correctly as I'm only finding solutions for resizing UIImageViews.

Another thought I had was maybe it shouldn't be a spriteNode as its just used for a button?

like image 915
Steve Avatar asked Dec 15 '16 01:12

Steve


1 Answers

First up, there's some primitive rules to follow, to get the best results.

  1. Only scale by factors of 2. ie 50%, 25%, 12.5% 6.25% etc.

    This way, any four pixels in your original image become 1 pixel in your scaled image, for each step down in scale size.

  2. Make your original image a square of an exponent of 2 in size. So: 128x128, 256x256, 512x512, etc. You've covered this already with your 2048x2048 sizing.

  3. Turn on mipmapping. This is off, by default, in SpriteKit, so you have to switch it on: https://developer.apple.com/reference/spritekit/sktexture/1519960-usesmipmaps

  4. Play with the different filtering modes to get the best reductions of noise and banding in your image: https://developer.apple.com/reference/spritekit/sktexture/1519659-filteringmode hint, linear will probably be better.

  5. As has always been the case, judicious use of Photoshop for manually scaling will give you the best results and least flexibility

like image 88
Confused Avatar answered Oct 31 '22 07:10

Confused