Search code examples
iosswiftuiimageuigraphicscontext

UIImage created doesn't appear as I would have expected?


iOS 10.2 swift 3.0

I am using these routines to cut, resize and recombine an image to display on an AppleTV. But despite the fact it reports the image as the correct size, it doesn't work the way I had expected/wanted.

What did I miss here?

func cropImage(image: UIImage, newRect: CGRect) -> UIImage {
    let img = CIImage(image: image)!.cropping(to: newRect)
    let image = UIImage(ciImage: img, scale: 1.0, orientation: image.imageOrientation)
    return image
}

func combine2LONGImage(imageUn: UIImage, imageDeux: UIImage) -> UIImage {
    let size = CGSize(width: imageUn.size.width + imageDeux.size.width, height: imageUn.size.height)
    UIGraphicsBeginImageContext(size)
    imageUn.draw(in: CGRect(x: 0, y: 0, width: imageUn.size.width, height: imageUn.size.height))
    imageDeux.draw(in: CGRect(x: imageUn.size.width, y: 0, width: imageDeux.size.width, height: imageDeux.size.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}


func resizeLONGImage(image: UIImage, newSize: CGSize) -> UIImage {
    UIGraphicsBeginImageContext(newSize)
    image.draw(in: CGRect(x:0, y:0, width: newSize.width, height: self.view.bounds.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

 let leftSide = CGRect(x: 0, y: 0, width:  (image2S?.size.width)!/2, height: self.view.bounds.height)


let leftImage = self.cropImage(image: image2S!, newRect: leftSide)
let rightSide = CGRect(x: (image2S?.size.width)!/2, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)

let rightImage = self.cropImage(image: image2S!, newRect: rightSide)
            print("20022017 \(leftImage) \(rightImage)")

let newLeftImage = self.resizeLONGImage(image: leftImage, newSize: CGSize(width: self.view.bounds.width, height: self.view.bounds.height))
let newRightImage = self.resizeLONGImage(image: rightImage, newSize: CGSize(width: self.view.bounds.width, height: self.view.bounds.height))
let superNewImage = self.combine2LONGImage(imageUn: newLeftImage, imageDeux: newRightImage)
print("19022017 newimage  \(self.image2P.bounds) \(leftImage.size.width) \(newLeftImage.size.height) \(superNewImage.size)")



self.image2P.image = superNewImage
self.image2P.contentMode = .left
self.image2P.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)

The image returned is [is the correct size [twice as long as the AppleTV screen, same height] ... but the contentMode fails me, it resizes the image it seems to that it fits on the screen!!]. I did a snapshot and I got this ...

enter image description here

Yes, it is a 3 & 4, but its the same as the 1 & 2.

The console is reporting?

19022017 previewPane 1920.0 1080.0 1920.0 1080.0
20022017 Optional(<UIImage: 0x60000009d9c0>, {1920, 768}) Optional(<UIImage: 0x60000009da10>, {1024, 768})
19022017 newimage  (0.0, 0.0, 1920.0, 1080.0) 1920.0 1080.0 (3840.0, 1080.0)

The superNewImage is 3840 wide and 1080 high, and I said just left justify it, but what is it doing?

If I load an image I created with Paint say that is the same size, and show it onscreen it works as I would have expected, half on screen, half off.

The original image I start with is here.

enter image description here

What I am looking to do is show only the first digit on screen so that the user of the app can scroll sideways to the second. The scrolling I got working, some fixing to do. And it works if I upload a preset image with the correct size [2 x width, same height]. But if I upload an image that is a subset, try and crop + combine it, no it doesn't work.

Just added a leftSide piece of code another whoops perhaps... still doesn't work. The first image I created the exact size worked, it looks like this ...

enter image description here

The original looks like this ...

enter image description here


Solution

  • I think you are mixing image size, desired image size, screen / view size...

    Try this in a Playground... I added your 2048x768 "1 2" image named "orig2048x1024.png"

    import UIKit
    import PlaygroundSupport
    
    var screenSize = CGSize(width: 1920, height: 1080)
    
    let containerView = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height))
    containerView.backgroundColor = UIColor.green
    
    
    func chopImageFromRect(image: UIImage, newRect: CGRect) -> UIImage {
        let img = CIImage(image: image)!.cropping(to: newRect)
        let image = UIImage(ciImage: img, scale: 1.0, orientation: image.imageOrientation)
        return image
    }
    
    func combine2LONGImage(imageUn: UIImage, imageDeux: UIImage) -> UIImage {
    
        let size = CGSize(width: imageUn.size.width + imageDeux.size.width, height: imageUn.size.height)
        UIGraphicsBeginImageContext(size)
    
        imageUn.draw(in: CGRect(x: 0, y: 0, width: imageUn.size.width, height: imageUn.size.height))
    
        imageDeux.draw(in: CGRect(x: imageUn.size.width, y: 0, width: imageDeux.size.width, height: imageDeux.size.height))
    
    
        let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    
    }
    
    func resizeLONGImage(image: UIImage, newSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContext(newSize)
        image.draw(in: CGRect(x:0, y:0, width: newSize.width, height: newSize.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
    
    
    var finalImage: UIImage?
    
    // original image size is 2048 x 768
    let image2S = UIImage(named: "orig2048x768.png")
    
    // target image size should be 3840 x 1080
    let targetImageSize = CGSize(width: screenSize.width * 2.0, height: screenSize.height)
    
    if let sz = image2S?.size {
    
        // get the left side - x: 0 y: 0 / 1024 x 768 - of image
        let leftHalf = chopImageFromRect(image: image2S!, newRect: CGRect(x: 0, y: 0, width: sz.width / 2, height: sz.height))
    
        // get the right side - x: 1024 y: 0 / 1024 x 768 - of image
        let rightHalf = chopImageFromRect(image: image2S!, newRect: CGRect(x: sz.width / 2, y: 0, width: sz.width / 2, height: sz.height))
    
        // target size for each is Half of the Target Image Size (double the screen width x the screen height)
        let targetHalfSize = CGSize(width: targetImageSize.width / 2, height: targetImageSize.height)
    
        // scale each half to targetHalfSize
        let newLH = resizeLONGImage(image: leftHalf, newSize: targetHalfSize)
        let newRH = resizeLONGImage(image: rightHalf, newSize: targetHalfSize)
    
        // combine the two newly-scaled halfs
        finalImage = combine2LONGImage(imageUn: newLH, imageDeux: newRH)
    
        // create an UIImageView the same size as the screen
        let imgView = UIImageView(frame: containerView.bounds)
    
        // set contentMode to .left
        imgView.contentMode = .left
    
        // set the image of the image view
        imgView.image = finalImage
    
        // add the image view to the screen
        containerView.addSubview(imgView)
    
    }
    
    
    PlaygroundPage.current.liveView = containerView
    PlaygroundPage.current.needsIndefiniteExecution = true