Click here to Skip to main content
14,574,491 members

Drawing into bitmaps and saving as a PNG in Swift on OS X

Rate this:
4.00 (1 vote)
Please Sign up or sign in to vote.
4.00 (1 vote)
4 May 2015CPOL
Drawing into bitmaps and saving as a PNG in Swift on OS X

Not an in depth post today. For small iOS Swift/SpriteKit game I'm writing for fun, I wanted a very basic grass sprite that could be scrolled; to create a parallax effect. This amounts to a 800x400 bitmap which contains sequential isosceles triangles of 40 pixels with random heights (of up to 400 pixels) and coloured using a lawn green colour.

Initially, I was creating an SKShapeNode and creating the triangles above but when scrolling the redrawing of these hurt performance, especially when running on the iOS Simulator hence the desire to use a sprite.

I had a go at creating these with Photoshop. Whilst switching to a sprite improved performance the look of the triangles drawn by hand wasn't as good as the randomly generated ones. Therefore, I thought I'd generate the sprite.

It wasn't really practical to do this on iOS as the file was needed in Xcode so I thought I'd try experimenting with a command line OS X (Cocoa) program in Swift. A GUI would possibly be nice to preview the results (and re-generate if needed) and to select the save-to file location but this solution sufficed.

I'd not done any non-iOS Swift development and never generated PNGs so various amounts of Googling and StackOverflow-ing was needed. Whilst the results of these searches were very helpful, I didn't come across anything showing a complete program to create a bitmap, draw into it and then save so the finished program is presented below. It's also available as a gist.

1:  import Cocoa  
3:  private func saveAsPNGWithName(fileName: String, bitMap: NSBitmapImageRep) -> Bool  
4:  {  
5:      let props: [NSObject:AnyObject] = [:]  
6:      let imageData = bitMap.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: props)  
8:      let myPath = NSFileManager.defaultManager().currentDirectoryPath  
10:      return imageData!.writeToFile(fileName, atomically: false)  
11:  }  
13:  private func drawGrassIntoBitmap(bitmap: NSBitmapImageRep)  
14:  {  
15:      var ctx = NSGraphicsContext(bitmapImageRep: bitmap)  
17:      NSGraphicsContext.setCurrentContext(ctx)  
19:      NSColor(red: 124 / 255, green: 252 / 255, blue: 0, alpha: 1.0).set()  
21:      let path = NSBezierPath()  
23:      path.moveToPoint(NSPoint(x: 0, y: 0))  
25:      for i in stride(from: 0, through: SIZE.width, by: 40)  
26:      {  
27:          path.lineToPoint(NSPoint(x: CGFloat(i + 20), y: CGFloat(arc4random_uniform(400))))  
28:          path.lineToPoint(NSPoint(x: i + 40, y: 0))  
29:      }  
31:      path.stroke()  
32:      path.fill()  
34:  }  
36:  let SIZE = CGSize(width: 800, height: 400)  
38:  println("\(Process.arguments[0])")  
40:  if Process.arguments.count != 2  
41:  {  
42:      println("usage: grass <file>")  
43:      exit(1)  
44:  }  
46:  let grass = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(SIZE.width), 
pixelsHigh: Int(SIZE.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, 
isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)  
48:  drawGrassIntoBitmap(grass!)  
49:  saveAsPNGWithName(Process.arguments[1], grass!)  

Image 1


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Team Leader
United Kingdom United Kingdom
My day job is mostly working in C++ with a bit of C#. I write a fair amount of command line based tools and really wish they could have a GUI front-end to them hence why I spend my spare time working with WPF.

I started a blog few years back but didn't do a lot with it. I've started describing some of the interesting programming things I come across on it. Please take a look.

Comments and Discussions

-- There are no messages in this forum --
Technical Blog
Posted 4 May 2015

Tagged as


3 bookmarked