简体   繁体   中英

Convert a Double Array to UIImage in swift

Is it possible to convert a double array to UIImage using UIImage function?

var ImageDouble = [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0]

UIImage function asks for String. I tried converting the array on individual element to strings and the whole thing to string, I get a nill result. Can someone help?

[Edit:]

As it seems I was not really clear on my problem. To make it more clear, I am developing a software which crops numbers & operators from a mathematical expression and shows me all the chunks one by one. Now, how do I go about it in Swift? :

Step-1: I have a grayscale image provided. I read it using UIImage function. I convert it to a custom RGBA function as follows so that I can deal on a pixel level like we do in MATLAB or Python or C++. The function is inspired from many websites's suggestions to use it.

struct Pixel {
var value: UInt32
var red: UInt8 {
    get { return UInt8(value & 0xFF) }
    set { value = UInt32(newValue) | (value & 0xFFFFFF00) }
}
var green: UInt8 {
    get { return UInt8((value >> 8) & 0xFF) }
    set { value = (UInt32(newValue) << 8) | (value & 0xFFFF00FF) }
}
var blue: UInt8 {
    get { return UInt8((value >> 16) & 0xFF) }
    set { value = (UInt32(newValue) << 16) | (value & 0xFF00FFFF) }
}
var alpha: UInt8 {
    get { return UInt8((value >> 24) & 0xFF) }
    set { value = (UInt32(newValue) << 24) | (value & 0x00FFFFFF) }
}

}

struct RGBA {
var pixels: UnsafeMutableBufferPointer<Pixel>
var width: Int
var height: Int
init?(image: UIImage) {
    guard let cgImage = image.CGImage else { return nil }
    width = Int(image.size.width)
    height = Int(image.size.height)
    let bitsPerComponent = 8
    let bytesPerPixel = 4
    let bytesPerRow = width * bytesPerPixel
    let imageData = UnsafeMutablePointer<Pixel>.alloc(width * height)
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue
    bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue
    guard let imageContext = CGBitmapContextCreate(imageData, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo) else { return nil }
    CGContextDrawImage(imageContext, CGRect(origin: CGPointZero, size: image.size), cgImage)
    pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height)
}

func toUIImage() -> UIImage? {
    let bitsPerComponent = 8
    let bytesPerPixel = 4
    let bytesPerRow = width * bytesPerPixel
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue
    bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue
    let imageContext = CGBitmapContextCreateWithData(pixels.baseAddress, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo, nil, nil)
    guard let cgImage = CGBitmapContextCreateImage(imageContext) else {return nil}
    let image = UIImage(CGImage: cgImage)
    return image
}

}

Step-2: Now I take one channel of the image [Red: it does not matter which one I take, since all the channels have same output] and apply my custom median filter of kernel size 5x5.

Step-3: Next, I do the binarization of the image using Nibblack approximation,where I used averaging filter and standard deviation.

Step-4: After that, I used connected component labelling to separate out different connected components of the image.

Step-5: Finally, I need to crop the labelled images and resize it. For cropping from the original image , I know the location by using a smart location algorithm. For resizing, I want to use Core Graphics Resizing filter. However, for that I need to convert my current output [a two-dimensional array or flattened] to UIImage or CGImage.

That's my real question: How do I convert to UIImage or CGImage from two-dimensional array or flattened array which are of type Array<Double> or Array<Int> ?

Try this:

var ImageDouble = [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0]
let images = ImageDouble.map{ UIImage(named: "\($0)")}

the map function will transform your array to another array.

Just try this:

var str:[String] = [];

for (var i=0;i<ImageDouble.count;i++){
   str.append(String(ImageDouble[i]));
}
print(str)

But why would you pass a String of numbers to an UIImage? Are images in your asset named as numbers?

Looks like you want to render 1, 2, etc into a bitmap.

First you need a function to do that, and then use flatMap on the array of doubles using this. This will ensure you get an array of UIImages in a safe way by filtering if any nil results when we try to create images.

func createNumberImage(number:Double) -> UIImage?{

    //Set a frame that you want.
    let frame = CGRect(x: 0, y: 0, width: 200, height: 200)
    let view = UIView(frame:frame )
    view.backgroundColor = UIColor.redColor()

    let label = UILabel(frame:frame)
    view.addSubview(label)

    label.font  = UIFont.systemFontOfSize(100);
    label.text = String(format: "%.1lf", arguments:[number])
    label.textAlignment = NSTextAlignment.Center
    view

    UIGraphicsBeginImageContext(view.bounds.size);
    view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return screenShot
}

let doubles = [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0]

//Get the array of UIImage objects.  
let images = doubles.flatMap { createNumberImage($0) }

You can use playground to verify this working. Also you might want to set proper background and text colors and font size to suite your requirements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM