I been trying to convert an UIImage to a matrix or a bitarray in swift but I don`t know how
import UIKit
import PlaygroundSupport
let bgimg = UIImage(named: "IMG_8565.JPG") // The image used as a background
let bgimgview = UIImageView(image: bgimg) // Create the view holding the image
bgimgview.frame = CGRect(x: 0, y: 0, width: 500, height: 500) // The size of the background image
let frontimg = UIImage(named: "spongebob.png") // The image in the foreground
let frontimgview = UIImageView(image: frontimg) // Create the view holding the image
frontimgview.frame = CGRect(x: 100, y: 200, width: 150, height: 150) // The size and position of the front image
bgimgview.addSubview(frontimgview) // Add the front image on top of the background
the last line contains the image and is what i`m trying to change into a matrix or a bitarray
also I know there are similar post but i hardly understand them, so please help me
mb you want just convert your image to the Data?
guard let image = UIImage(named: "IMG_8565.JPG") else { return }
guard let data = image?.jpegData(compressionQuality: 1.0) else { return }
compressionQuality: 1.0 - it's max quality for your image.
Related
I'm trying to draw multiple images into a single PDFPage.
Looking at the docs and over StackOverflow seems like the best I got is to use PDFPage with an UIImage initializer like so:
let pdfPage = PDFPage(image: image)
But it just creates a page with a full-page image. I tried to draw the images using CGContext but I don't understand how to use PDFPage within a drawing context for it to draw the images rapidly like in the example below.
let bounds = page.bounds(for: .cropBox)
// Create a `UIGraphicsImageRenderer` to use for drawing an image.
let renderer = UIGraphicsImageRenderer(bounds: bounds, format: UIGraphicsImageRendererFormat.default())
let image = renderer.image { (context) in
// How do I rapidly draw them here?
}
Any help will be highly appreciated!
The result I get with PDFPage(image: <UIImage>) vs expected result:
You probably need to improve the positioning logic for the image in the loop, but this should point you to the right direction.
import UIKit
import PDFKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let pdfView = PDFView()
pdfView.frame = CGRect(x: 0, y: 50, width: view.frame.width, height: view.frame.height - 50)
if let d = createPDFDocument() {
pdfView.document = d
}
view.addSubview(pdfView)
}
func createPDFDocument() -> PDFDocument? {
let pdfDocument = PDFDocument()
let page = PDFPage()
let bounds = page.bounds(for: .cropBox)
let imageRenderer = UIGraphicsImageRenderer(bounds: bounds, format: UIGraphicsImageRendererFormat.default())
let image = imageRenderer.image { (context) in
context.cgContext.saveGState()
context.cgContext.translateBy(x: 0, y: bounds.height)
context.cgContext.concatenate(CGAffineTransform.init(scaleX: 1, y: -1))
page.draw(with: .mediaBox, to: context.cgContext)
context.cgContext.restoreGState()
// Improve logic for image position
Range(1...4).forEach { value in
let image = UIImage(named: "YOUR_IMAGE_NAME")
let rect = CGRect(x: 50 * value, y: 0, width: 40, height: 100)
image?.draw(in: rect)
}
}
let newPage = PDFPage(image: image)!
pdfDocument.insert(newPage, at: 0)
return pdfDocument
}
}
I am working on creating a small word guessing app for a school assignment in uikit and I have been trying to figure out a way to overlay an image that updates based on the amount of incorrect guesses left on top of another image. I've spent almost 2 1/2 hours checking and I could not find a single method that worked.
So far this is what I've tried
let bgimg = UIImage(named: "background") // The image used as a background
let bgimgview = UIImageView(image: bgimg) // Create the view holding the image
bgimgview.frame = CGRect(x: 0, y: 0, width: 500, height: 500) // The size of the background image
let frontimg = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)") // The image in the foreground
let frontimgview = UIImageView(image: frontimg) // Create the view holding the image
frontimgview.frame = CGRect(x: 150, y: 300, width: 50, height: 50) // The size and position of the front image
bgimgview.addSubview(frontimgview) // Add the front image on top of the background
I commented this one out so that my code could work
let bottomImage = UIImage(named: "background")!
// let topImage = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)")!
// let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 100, height: 100))
// let newSize = rect.size // set this to what you need
// UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
//
// bottomImage.draw(in: rect)
// topImage.draw(in: rect)
//
// let newImage = UIGraphicsGetImageFromCurrentImageContext()
// UIGraphicsEndImageContext()
// }
//
// var backgroundImageButton: UIButton! {
// backgroundImageButton.setBackgroundImage(newImage)
You should be able to do this by adjusting the alpha value of the foreground image view. Alpha controls the transparency of a view-- an alpha of 1.0 makes it opaque, a value of 0 is invisible, and values between 0 and 1 make a view more or less transparent. If you have the two image views aligned so that one covers the other, you can set the foreground image alpha to any value from 0 to 1 to adjust how transparent it is.
I've been trying to merge two images where one is on top and the other at the bottom. This code below doesn't seem to work. The x coordinator is correct but the y doesn't seem right and it crops the top image when I alter it. What am I doing wrong?
func combine(bottomImage: Data, topImage: Data) -> UIImage {
let bottomImage = UIImage(data: topImage)
let topImage = UIImage(data: bottomImage)
let size = CGSize(width: bottomImage!.size.width, height: bottomImage!.size.height + topImage!.size.height)
UIGraphicsBeginImageContext(size)
let areaSizeb = CGRect(x: 0, y: 0, width: bottomImage!.size.width, height: bottomImage!.size.height)
let areaSize = CGRect(x: 0, y: 0, width: topImage!.size.width, height: topImage!.size.height)
bottomImage!.draw(in: areaSizeb)
topImage!.draw(in: areaSize)
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
You are drawing both images into the same rect. You also should not use force-unwrapping. That causes your app to crash if anything goes wrong.
There are also various other small mistakes.
Change your function like this:
// Return an Optional so we can return nil if something goes wrong
func combine(bottomImage: Data, topImage: Data) -> UIImage? {
// Use a guard statement to make sure
// the data can be converted to images
guard
let bottomImage = UIImage(data: bottomImage),
let topImage = UIImage(data: topImage) else {
return nil
}
// Use a width wide enough for the widest image
let width = max(bottomImage.size.width, topImage.size.width)
// Make the height tall enough to stack the images on top of each other.
let size = CGSize(width: width, height: bottomImage.size.height + topImage.size.height)
UIGraphicsBeginImageContext(size)
let bottomRect = CGRect(
x: 0,
y: 0,
width: bottomImage.size.width,
height: bottomImage.size.height)
// Position the bottom image under the top image.
let topRect = CGRect(
x: 0,
y: bottomImage.size.height,
width: topImage.size.width,
height: topImage.size.height)
bottomImage.draw(in: bottomRect)
topImage!.draw(in: topRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
(And you should really be using a UIGraphicsImageRenderer rather than than calling UIGraphicsBeginImageContext()/ UIGraphicsEndImageContext().)
Edit:
Note that if the 2 images are different widths the above code will leave a "dead space" on the right of the narrower image. You could also make the code center the narrower image, or scale it up to be the same width. (If you do scale it up I suggest scaling it up in both dimensions to preserve the original aspect ratio. Otherwise it will look stretched and unnatural.)
I have a single image. And I have a collection view with banner images. Now,I need to combine these 2 images into single image without affecting their quality and height so that I could be able to download the merged image. I searched but couldn't find proper solutions for swift 3. My code is given as:
As per as your question You have to add two images and show up in a single UIImageView.
Here is a simple example of adding two images vertically and showing up in an UIImageView -
let topImage = UIImage(named: "image1.png") // 355 X 200
let bottomImage = UIImage(named: "image2.png") // 355 X 60
let size = CGSize(width: (topImage?.size.width)!, height: (topImage?.size.height)! + (bottomImage?.size.height)!)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
topImage?.draw(in: CGRect(x:0, y:0, width:size.width, height: (topImage?.size.height)!))
bottomImage?.draw(in: CGRect(x:0, y:(topImage?.size.height)!, width: size.width, height: (bottomImage?.size.height)!))
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
// I've added an UIImageView, You can change as per your requirement.
let mergeImageView = UIImageView(frame: CGRect(x:0, y: 200, width: 355, height: 260))
// Here is your final combined images into a single image view.
mergeImageView.image = newImage
I hope it will help you to start with.
Please forgive my ignorance.. I'm new to Swift and I'm trying to sort this out..
I have a custom NSImageView (called 'AdFrame') that draws two images within NSRects. I want the bottom image to change when a user inputs a certain number.
It draws fine when loading the default image (upon starting the app), but won't update with the new image
Here is the function (drawImages) in the NSImageView class:
var adUrl = NSURL(string: "ftp://mysite.com/12345.jpg")
let topImage = NSImage(named: "logo")
let bottomImage = NSImage(byReferencingURL: adUrl!)
let bottomRect = NSRect.init(x: 0, y: 0, width: 500, height: 200)
let topRect = NSRect.init(x: 250, y: 250, width: 100, height: 75)
adImage.drawInRect(bottomRect)
logoImage!.drawInRect(topRect)
The function to update the bottom image, from another class:
#IBAction func updateImage(sender: AnyObject) {
let theADFrame = AdFrame()
let adNumber = adNumTF.stringValue
theADFrame.adUrl = NSURL(string: "ftp://mysite.com/\(adNumber).jpg")
theADFrame.drawImages()
}
When running this function, the new url is being passed to the ImageView, but the images aren't updating in my app.
Thanks
drawImages uses always the same URL (12345). You might pass the URL to drawImages as a parameter.
func drawImages(url : NSURL) {
let topImage = NSImage(named: "logo")
let bottomImage = NSImage(byReferencingURL: url)
let bottomRect = NSRect.init(x: 0, y: 0, width: 500, height: 200)
let topRect = NSRect.init(x: 250, y: 250, width: 100, height: 75)
adImage.drawInRect(bottomRect)
logoImage!.drawInRect(topRect)
}
and call it in updateImage
let adUrl = NSURL(string: "ftp://mysite.com/\(adNumber).jpg")!
theADFrame.adUrl = adUrl
theADFrame.drawImages(adUrl)
and the first call
drawImages(NSURL(string: "ftp://mysite.com/12345.jpg")!)