---
title: How to Use UIkit for Low-Level Image Processing in Swift
description: Want to create your own image filtering application to increase and decrease contrast or go grayscale? It's easier than you might think!
image: https://blog.avenuecode.com/hubfs/car-communication-3100980_1920.jpg
---

[AvenueCode.com](https://avenuecode.com) [News](https://avenuecode.com/news) [Contact](https://avenuecode.com/contact)

[![Avenue Code Snippets Logo](https://blog.avenuecode.com/hubfs/Avenue%20Code%20New%20Logos%20-%202023/AC-Snippets---Black.png)](https://blog.avenuecode.com/?hsLang=en-us) *menu*

- Technology
  
  [Cloud](https://blog.avenuecode.com/blog/topic/cloud?hsLang=en-us) [Delivery Infrastructure](https://blog.avenuecode.com/blog/topic/delivery-infrastructure?hsLang=en-us) [Web Experience](https://blog.avenuecode.com/blog/topic/web-experience?hsLang=en-us) [Agile Mindset](https://blog.avenuecode.com/blog/topic/agile-mindset?hsLang=en-us) [Quality First](https://blog.avenuecode.com/blog/topic/quality-first?hsLang=en-us)
  
  [Design](https://blog.avenuecode.com/blog/topic/design?hsLang=en-us) [Solution Architecture](https://blog.avenuecode.com/blog/topic/solution-architecture?hsLang=en-us) [Data & ML](https://blog.avenuecode.com/blog/topic/data-and-machine-learning?hsLang=en-us) [Mobile Experience](https://blog.avenuecode.com/blog/topic/mobile-experience?hsLang=en-us)
- [Whitepapers](https://blog.avenuecode.com/blog/topic/whitepapers?hsLang=en-us)
- [Spotlight](https://blog.avenuecode.com/blog/topic/spotlight?hsLang=en-us)
- [Extraordinary Women in Tech](https://blog.avenuecode.com/blog/topic/extraordinary-women-in-tech?hsLang=en-us)
- [Avenue Code Culture](https://blog.avenuecode.com/blog/topic/avenue-code-culture?hsLang=en-us)

- [Cloud](https://blog.avenuecode.com/blog/topic/cloud?hsLang=en-us)
- [Design](https://blog.avenuecode.com/blog/topic/design?hsLang=en-us)
- [Delivery Infrastructure](https://blog.avenuecode.com/blog/topic/delivery-infrastructure?hsLang=en-us)
- [Solution Architecture](https://blog.avenuecode.com/blog/topic/solution-architecture?hsLang=en-us)
- [Web Experience](https://blog.avenuecode.com/blog/topic/web-experience?hsLang=en-us)
- [Data & ML](https://blog.avenuecode.com/blog/topic/data-and-machine-learning?hsLang=en-us)
- [Agile Mindset](https://blog.avenuecode.com/blog/topic/agile-mindset?hsLang=en-us)
- [Mobile Experience](https://blog.avenuecode.com/blog/topic/mobile-experience?hsLang=en-us)
- [Quality First](https://blog.avenuecode.com/blog/topic/quality-first?hsLang=en-us)
- [Whitepapers](https://blog.avenuecode.com/blog/topic/whitepapers?hsLang=en-us)
- [Spotlight](https://blog.avenuecode.com/blog/topic/spotlight?hsLang=en-us)
- [Extraordinary Women in Tech](https://blog.avenuecode.com/blog/topic/extraordinary-women-in-tech?hsLang=en-us)
- [Avenue Code Culture](https://blog.avenuecode.com/blog/topic/avenue-code-culture?hsLang=en-us)

# [How to Use UIkit for Low-Level Image Processing in Swift](https://blog.avenuecode.com/how-to-use-uikit-for-low-level-image-processing-in-swift)

- [Tweet](https://twitter.com/share)

*perm\_identity* [Khalid Asad](https://blog.avenuecode.com/how-to-use-uikit-for-low-level-image-processing-in-swift/author/khalid-asad?hsLang=en-us)

*schedule* 2/26/20 3:00 PM

Ever thought about creating your own Instagram or image filtering application but don't know exactly how to approach it? Have some old C++ code but don’t want to go through all the wrappers? This guide is meant to show some of the basics of image processing in Swift using only UIkit.

Computers use pixels to display images. In general, a pixel (the smallest controllable element in an image) is composed of 3 or 4 colors of varying intensities:

*Red, Green, and Blue* (**RGB**)  
or  
*Cyan, Magenta, Yellow, and Black*

The number of distinct colors that can be represented by a pixel depends on the number of bits per pixel (bpp). A 1 bpp image uses 1-bit for each pixel, so each pixel can be either on or off. Each additional bit doubles the number of colors available, so a 2 bpp image can have 4 colors, and a 3 bpp image can have 8 colors.

The basic contrast and brightness adjustments are transformations of the form:

> 𝑓(𝑥)=𝛼𝑥+𝛽f(x)=αx+β

(with the result rounded to an integer and clamped to the range \[0,255\]\[0,255\]). Here 𝑥x is a color component value (R, G, or B). The slope 𝛼α controls contrast (𝛼>1α>1 means more contrast and 0<𝛼<10<α<1 less contrast). For easier separation of “brightness” and “contrast” modifications, the formula can be written like this:

> 𝑓(𝑥)=𝛼(𝑥−128)+128+𝑏f(x)=α(x−128)+128+b

where 𝑏b controls brightness.

Now that we have our basics covered, we can dive into the Swift portion!

Let’s grab our image, then take the cgImage of it:

![KA 1](https://blog.avenuecode.com/hs-fs/hubfs/KA%201.jpg?width=512&name=KA%201.jpg)

 

This image pretty accurately represents what some developers face on a daily basis!

```
guard let image = UIImage(named: “image”),       let cgImage = image.cgImage else { return }
```

We want to redraw this image with a specific Image Core Graphics Context, so let’s generate what we will need for this:

```
var colorSpace = CGColorSpaceCreateDeviceRGB()var bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValuebitmapInfo |= CGImageAlphaInfo.premultipliedLast.rawValue & CGBitmapInfo.alphaInfoMask.rawValuelet width = Int(image.size.width)let height = Int(image.size.height)var bytesPerRow = width * 4let imageData = UnsafeMutablePointer<Pixel>.allocate(capacity: width * height)
```

By generating an UnsafeMutablePointer with Pixels (we already know that they are composed of RGB values, as well as an Alpha multiplier), we can manipulate CGContext with information about the size and bitmap (32-bit, big endian format).

```
guard let imageContext = CGContext(     data: imageData,     width: width,     height: height,     bitsPerComponent: 8,     bytesPerRow: bytesPerRow,     space: colorSpace,     bitmapInfo: bitmapInfo) else { return nil }
```

After generating our CGContext struct, we are ready to redraw the image:

```
imageContext.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
```

Now, given that the pointer is generated and updated, we can continue to our interface of the buffer by starting at that pointer:

```
let pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height)
```

Given this buffer pointer, we can iterate through each pixel to calculate the total individual amounts of RGB pixels:

```
for y in 0..<height {     for x in 0..<width {          let index = y * width + x          let pixel = pixels[index]          totalRed += Int(pixel.red)          totalGreen += Int(pixel.green)          totalBlue += Int(pixel.blue)     }}
```

Now calculate the averages by dividing by the pixel area.

```
let avgRed = totalRed / pixelArealet avgGreen = totalGreen / pixelArealet avgBlue = totalBlue / pixelArea
```

Finally, we’re ready to manipulate the pixels!

```
for y in 0..<height {     for x in 0..<width {          let index = y * width + x          var pixel = pixels[index]          let redDelta = Int(pixel.red) - avgRed          let greenDelta = Int(pixel.green) - avgGreen          let blueDelta = Int(pixel.blue) - avgBlue          pixel.red = UInt8(max(min(255, avgRed + 2 * redDelta), 0))          pixel.blue = UInt8(max(min(255, avgBlue + 2 * blueDelta), 0)) .     pixel.green = UInt8(max(min(255, avgGreen + 2 * greenDelta), 0))                    pixels[index] = pixel      }}
```

The above code can be done in any way you want to manipulate contrast. In our case, we simply want to increase the contrast. We can do this by adding a delta with a multiplier of 2 to each of the pixels. Remember the max value is 255, and the min is 0.

Now we can create the CGContext (like we did in the beginning) and use the makeImage() function to generate an image:

```
guard let newCGImage = context.makeImage() else { return nil }return UIImage(cgImage: newCGImage)
```

Let’s see how the output image turned out on the simulator!

![KA 2](https://blog.avenuecode.com/hs-fs/hubfs/KA%202.png?width=512&name=KA%202.png)Now that we increased the contrast, we can see darker colors.

Great! Let’s try the reverse by decreasing the contrast by the delta:

![KA 3](https://blog.avenuecode.com/hs-fs/hubfs/KA%203.png?width=512&name=KA%203.png)Woah! We created a photo negative!

We decreased the contrast so much that we ended up creating a photo negative.

Let’s try grayscale using this forumla:

> 𝑦=0.3𝑅+0.6𝐺+0.1𝐵

![KA 4](https://blog.avenuecode.com/hs-fs/hubfs/KA%204.png?width=512&name=KA%204.png)Pretty cool!

With the use of Unsafe pointers and CGContext from Core Graphics, as well as a little bit of tinkering with RGB values, we can achieve anything with image filters in Swift! Congratulations, you now know how to create your very own Instagram image filtering application!

Access to the code is available [here](https://github.com/khalid-asad/Image-Processor).

---

### Author

# Khalid Asad

 Khalid Asad is a Senior iOS Engineer at Avenue Code. Based in SF and originally from Toronto, he is a foodie who loves challenging projects, hockey, and hiking.

---

### Related Posts

### Swift and the Hidden Power of Enums

[READ MORE](https://blog.avenuecode.com/swift-and-the-hidden-power-of-enums?hsLang=en-us)

### What You Need to Know about Swift Generics

[READ MORE](https://blog.avenuecode.com/what-you-need-to-know-about-swift-generics?hsLang=en-us)

### Leave a Comment!

### Avenue Code Social

[![Facebook Icon](https://blog.avenuecode.com/hubfs/Images/Blog/facebook.png?t=1486470796564)](https://www.facebook.com/avenuecode)

[![Twitter Icon](https://blog.avenuecode.com/hubfs/Images/Blog/twitter.png?t=1486470796842)](https://twitter.com/AvenueCode)

[![LinkedIn Icon](https://blog.avenuecode.com/hubfs/Images/Blog/linkedin.png?t=1486470796556)](https://www.linkedin.com/company/avenue-code)

### Newsletter

Want to stay on top of all tips and news from Avenue Code?

### Popular Snippets

![Primary Logo AvenueCode Inverted.png](https://blog.avenuecode.com/hs-fs/hubfs/Images/Logos/Primary%20Logo%20AvenueCode%20Inverted.png?width=1104&name=Primary%20Logo%20AvenueCode%20Inverted.png "Primary Logo AvenueCode Inverted.png")

### About Us

- [Who We Are](https://www.avenuecode.com/who-we-are)
- [What We Do](https://www.avenuecode.com/what-we-do)
- [Portfolio](https://www.avenuecode.com/portfolio)
- [Partners](https://www.avenuecode.com/partners)
- [News](https://www.avenuecode.com/news)
- [Events](https://www.avenuecode.com/events)
- [Blog](https://blog.avenuecode.com/)
- [Contact](https://www.avenuecode.com/contact)

### Our Offices

San Francisco

[+1 415 766 4178](tel:+553125161448) [ac.inquiries@avenuecode.com](mailto:brazil.info@avenuecode.com)

Belo Horizonte

[+55 31 2516 1448](tel:+553125161448) [brazil.info@avenuecode.com](mailto:brazil.info@avenuecode.com)

São Paulo

[+55 11 3205 3232](tel:+553125161448) [brazil.info@avenuecode.com](mailto:brazil.info@avenuecode.com)

### We're Hiring!

- [Belo Horizonte](https://www.avenuecode.com/who-we-are)
- [New York](https://www.avenuecode.com/what-we-do)
- [San Francisco](https://www.avenuecode.com/portfolio)
- [São Paulo](https://www.avenuecode.com/partners)

---

©2015 - 2017 Avenue Code

[![Facebook Icon](https://blog.avenuecode.com/hubfs/Images/Icons/facebook-2.png)](https://www.facebook.com/avenuecode) [![Twitter Icon](https://blog.avenuecode.com/hubfs/Images/Icons/twitter-2.png)](https://twitter.com/AvenueCode) [![LinkedIn Icon](https://blog.avenuecode.com/hubfs/Images/Icons/linkedin-2.png)](https://www.linkedin.com/company/avenue-code) [![Glassdoor Icon](https://blog.avenuecode.com/hubfs/Images/Icons/glassdoor-icon-1.png)](https://www.glassdoor.com/Overview/Working-at-Avenue-Code-EI_IE456173.11,22.htm) [![YouTube Icon](https://blog.avenuecode.com/hubfs/Images/Icons/youtube-2.png)](https://www.youtube.com/user/AvenueCodePlay)

Please enable JavaScript to view the [comments powered by Disqus.](http://disqus.com/?ref_noscript)

© 2026 Avenue Code

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Khalid Asad",
    "url" : "https://blog.avenuecode.com/author/khalid-asad"
  },
  "dateModified" : "2022-10-10T20:27:48.365Z",
  "datePublished" : "2020-02-26T18:00:00.000Z",
  "headline" : "How to Use UIkit for Low-Level Image Processing in Swift",
  "image" : [ "https://blog.avenuecode.com/hubfs/car-communication-3100980_1920.jpg" ],
  "mainEntityOfPage" : {
    "@id" : "https://blog.avenuecode.com/how-to-use-uikit-for-low-level-image-processing-in-swift",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://blog.avenuecode.com/hubfs/Avenue%20Code%20New%20Logos%20-%202023/Avenue%20Code-primary%20versions_LOGO%20HORIZONTAL%20group%201-7.png"
    },
    "name" : "Avenue Code"
  }
}
```