ios


How to create an image pixel by pixel


I want to create an UIImage pixel by pixel with swift 3
I have search but i couldn't find a code who actually works
So let me explain, I have an array with characters
var array = ["w", "x", "y", "x", "y", "y", "y", "x", "x", "x", "w", "x", "y", "w", "y"] //there will be something like 26 millions of those
if it's w, the color of the pixel is blue
if it's x, the color of the pixel is red
if it's y, the color of the pixel is green
if it's v, the color of the pixel is black
I want to create an image from those characters and store it in the photos
Any thoughts??
Thanks for your answers
You can create a CGContext and then retrieve the data buffer for that image, and then fill that buffer with values corresponding to your string values:
func createImage(width: Int, height: Int, from array: [String], completionHandler: #escaping (UIImage?, String?) -> Void) {
DispatchQueue.global(qos: .utility).async {
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bytesPerPixel = 4
let bitsPerComponent = 8
let bytesPerRow = bytesPerPixel * width
let bitmapInfo = RGBA32.bitmapInfo
guard array.count == width * height else {
completionHandler(nil, "Array size \(array.count) is incorrect given dimensions \(width) x \(height)")
return
}
guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else {
completionHandler(nil, "unable to create context")
return
}
guard let buffer = context.data else {
completionHandler(nil, "unable to get context data")
return
}
let pixelBuffer = buffer.bindMemory(to: RGBA32.self, capacity: width * height)
for (index, string) in array.enumerated() {
switch string {
case "w": pixelBuffer[index] = .blue
case "x": pixelBuffer[index] = .red
case "y": pixelBuffer[index] = .green
case "v": pixelBuffer[index] = .black
default: completionHandler(nil, "Unexpected value: \(string)"); return
}
}
let cgImage = context.makeImage()!
let image = UIImage(cgImage: cgImage)
// or
//
// let image = UIImage(cgImage: cgImage, scale: UIScreen.main.scale, orientation: .up)
completionHandler(image, nil)
}
}
If there are 26 million pixels, you probably want to make this asynchronous to avoid blocking the main queue.
By the way, the above uses this struct:
struct RGBA32: Equatable {
private var color: UInt32
var redComponent: UInt8 {
return UInt8((color >> 24) & 255)
}
var greenComponent: UInt8 {
return UInt8((color >> 16) & 255)
}
var blueComponent: UInt8 {
return UInt8((color >> 8) & 255)
}
var alphaComponent: UInt8 {
return UInt8((color >> 0) & 255)
}
init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) {
color = (UInt32(red) << 24) | (UInt32(green) << 16) | (UInt32(blue) << 8) | (UInt32(alpha) << 0)
}
static let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
static func ==(lhs: RGBA32, rhs: RGBA32) -> Bool {
return lhs.color == rhs.color
}
static let black = RGBA32(red: 0, green: 0, blue: 0, alpha: 255)
static let red = RGBA32(red: 255, green: 0, blue: 0, alpha: 255)
static let green = RGBA32(red: 0, green: 255, blue: 0, alpha: 255)
static let blue = RGBA32(red: 0, green: 0, blue: 255, alpha: 255)
}
To save the image, you can do:
createImage(width: width, height: height, from: array) { image, errorMessage in
guard let image = image, errorMessage == nil else {
print(errorMessage!)
return
}
DispatchQueue.main.async {
self.imageView.image = image
UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)
}
}
Where
func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: Any?) {
guard error == nil else {
print(error!.localizedDescription)
return
}
print("image saved")
}

Related Links

Realm Browser not allowing me to open files
Master-detail segue from DetailViewController with back button
Change date format using NSDateFormatter
How passing data with multiple prepareforsegue in a uitableviewcell swift
UITextViewDelegate in non viewcontroller class
How can I get indexPath of a uiview on a cell - iOS
How to allow audio to continue to play when app is backgrounded?
How to limit the pulling distance with a refresh control?
Image fits into UICollectionView Cell
Caching the downloaded data
Core Location and Google Maps
(Objective C) NSDate is nil to convert a date in String
Swift need to reload TableView that is contained within a containerView
Remove iAds from SKScene
Adjust UICollectionView Size Dynamically to Ensure No Inter Item Spacing
How to replace Detail in UISplitViewController in Swift?

Categories

HOME
sbt
codeigniter
f#
jsp
ssl-certificate
auth0
x-editable
apt-get
order
xamarin.forms-listview
api.ai
vsix
restsharp
whitespace
coreos
deserialization
graphcool
abaqus
accelerated-mobile-page
urlrewriter.net
robotium
precision
digital-logic
unsigned-integer
text-parsing
trial
asp.net-identity-2
solarwindslem
gcp
reed-solomon
seh
spring-websocket
haxm
ecdsa
drupal-webform
atlassian-bitbucketserver
spark-submit
karnaugh-map
invalidate
oracle-aq
ammonite
master-data-management
paypal-webhooks
gpt
asp.net-mvc-custom-filter
vispy
nsd
data-fitting
android-number-picker
scrutinizer
trello.net
asp.net-webpages
domo
dnx
hypervisor
avalonedit
cbc-mode
iphone-5
structured-programming
spatial-index
solr-boost
windows-universal
emberfire
conditional-statements
words
applicationstate
laravel-validation
gdk
datacontractserializer
controlsfx
sonata-media-bundle
cfile
mongo-shell
freemind
datasift-python
flash-cs4
sugar.js
wow64
mainwindow
sizzle
wpf-4.0
msxsl
ria
hpple
letter-spacing
nsinvocation
facebook-authentication
mkmapviewdelegate
unitils
seam-conversation
spquery
excel-web-query
webshop
msn-messenger
drwatson
cracker
gedcom
geneva-framework

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App