Below is the code for the rear camera, I tried adding rear camera is activated but I receive an error.
func addImagePickerToContainerView(){
imagePickers = UIImagePickerController()
if UIImagePickerController.isCameraDeviceAvailable( UIImagePickerControllerCameraDevice.front) {
imagePickers?.delegate = self
imagePickers?.sourceType = UIImagePickerControllerSourceType.camera
imagePickers?.cameraDevice = .rear
addChildViewController(imagePickers!)
// Add the child's View as a subview
self.cameraContainerView.addSubview((imagePickers?.view)!)
self.cameraContainerView.addSubview(layerKTP)
imagePickers?.view.frame = cameraContainerView.bounds
imagePickers?.allowsEditing = false
imagePickers?.showsCameraControls = false
imagePickers?.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
}
Message from debugger: Terminated due to memory issue
Try with below code
extension UIImage
{
func resizeImage(toSize size:CGSize, scale:CGFloat) ->UIImage
{
let imageRect = CGRect(origin: CGPoint(x:0.0, y:0.0), size: size)
UIGraphicsBeginImageContextWithOptions(size, false, scale)
self.draw(in: imageRect)
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resizedImage!
}
}
//Use this method like
let resizedImage = selectedImg.resizeImage(toSize:CGSize(width:100.0, height:100.0), scale: UIScreen.main.scale)
Related
I got an AsyncImage and want to use UIImageWriteToSavedPhotosAlbum for save my AsyncImage to user library.
I used Paul Hudson course for find what to do but it downloads an empty white picture on library on my iPhone and on simulator.
Here's the code:
func snapshot() -> UIImage {
let controller = UIHostingController(rootView: self)
let view = controller.view
let targetSize = controller.view.intrinsicContentSize
view?.bounds = CGRect(origin: .zero, size: targetSize)
view?.backgroundColor = .blue
let renderer = UIGraphicsImageRenderer(size: targetSize)
return renderer.image { _ in
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
}`
On the view:
`Button("Save to image") {
let image = AstronomyImageView(astronomy: article) //AsyncImage
let uiImage: UIImage = image.snapshot()
UIImageWriteToSavedPhotosAlbum(uiImage, nil, nil, nil)
}```
I'm trying to use the new Detect and Track Objects with ML Kit on iOS however I seem to be running into a roadblock with the object detection bounding box.
Using a lego figure as an example, the image orientation is converted to always be .up as per the documentation however the bounding box almost seems to be rotated 90 degrees to the correct dimensions despite the image orientation being correct. This similar behaviour exists on other objects too with the box being offset.
let options = VisionObjectDetectorOptions()
options.detectorMode = .singleImage
options.shouldEnableMultipleObjects = false
let objectDetector = Vision.vision().objectDetector(options: options)
let image = VisionImage(image: self.originalImage)
objectDetector.process(image) { detectedObjects, error in
guard error == nil else {
print(error)
return
}
guard let detectedObjects = detectedObjects, !detectedObjects.isEmpty else {
print("No objects detected")
return
}
let primaryObject = detectedObjects.first
print(primaryObject as Any)
guard let objectFrame = primaryObject?.frame else{return}
print(objectFrame)
self.imageView.image = self.drawOccurrencesOnImage([objectFrame], self.originalImage)
}
and the function that draws the red box;
private func drawOccurrencesOnImage(_ occurrences: [CGRect], _ image: UIImage) -> UIImage? {
let imageSize = image.size
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)
image.draw(at: CGPoint.zero)
let ctx = UIGraphicsGetCurrentContext()
ctx?.addRects(occurrences)
ctx?.setStrokeColor(UIColor.red.cgColor)
ctx?.setLineWidth(20)
ctx?.strokePath()
guard let drawnImage = UIGraphicsGetImageFromCurrentImageContext() else {
return nil
}
UIGraphicsEndImageContext()
return drawnImage
}
The image dimensions, according to image.size is (3024.0, 4032.0) and the box frame is (1274.0, 569.0, 1299.0, 2023.0). Any insight to this behaviour would be must appreciated.
Ended up not scaling the image properly which caused the misalignment.
This function ended up fixing my problems.
public func updateImageView(with image: UIImage) {
let orientation = UIApplication.shared.statusBarOrientation
var scaledImageWidth: CGFloat = 0.0
var scaledImageHeight: CGFloat = 0.0
switch orientation {
case .portrait, .portraitUpsideDown, .unknown:
scaledImageWidth = imageView.bounds.size.width
scaledImageHeight = image.size.height * scaledImageWidth / image.size.width
case .landscapeLeft, .landscapeRight:
scaledImageWidth = image.size.width * scaledImageHeight / image.size.height
scaledImageHeight = imageView.bounds.size.height
}
DispatchQueue.global(qos: .userInitiated).async {
// Scale image while maintaining aspect ratio so it displays better in the UIImageView.
var scaledImage = image.scaledImage(
with: CGSize(width: scaledImageWidth, height: scaledImageHeight)
)
scaledImage = scaledImage ?? image
guard let finalImage = scaledImage else { return }
DispatchQueue.main.async {
self.imageView.image = finalImage
self.processImage(finalImage)
}
}
}
This is the code I am using
extension UIImage {
var ellipseMasked: UIImage? {
guard let cgImage = cgImage else { return nil }
let rect = CGRect(origin: .zero, size: size)
return UIGraphicsImageRenderer(size: size, format: imageRendererFormat)
.image{ _ in
UIBezierPath(ovalIn: rect).addClip()
UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
.draw(in: rect)
}
}
}
This is the image I got
The background color is black.
How can I make the background transparent?
I tried different ways but haven't made it work yet.
You can subclass UIImageView and mask its CALayer instead of clipping the image itself:
extension CAShapeLayer {
convenience init(path: UIBezierPath) {
self.init()
self.path = path.cgPath
}
}
class EllipsedView: UIImageView {
override func layoutSubviews() {
super.layoutSubviews()
layer.mask = CAShapeLayer(path: .init(ovalIn: bounds))
}
}
let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
let iv = EllipsedView(image: profilePicture)
edit/update
If you need to clip the UIImage itself you can do it as follow:
extension UIImage {
var ellipseMasked: UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
UIBezierPath(ovalIn: .init(origin: .zero, size: size)).addClip()
draw(in: .init(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
For iOS10+ you can use UIGraphicsImageRenderer.
extension UIImage {
var ellipseMasked: UIImage {
let rect = CGRect(origin: .zero, size: size)
let format = imageRendererFormat
format.opaque = false
return UIGraphicsImageRenderer(size: size, format: format).image{ _ in
UIBezierPath(ovalIn: rect).addClip()
draw(in: rect)
}
}
}
let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
profilePicture.ellipseMasked
Here are two solutions using SwiftUI.
This solution can be used to clip the image shape to a circle.
Image("imagename").resizable()
.clipShape(Circle())
.scaledToFit()
This solution can be used to get more of an eclipse or oval shape from the image.
Image("imagename").resizable()
.cornerRadius(100)
.scaledToFit()
.padding()
I am currently working on an Image app where I can put a Text Sticker that made with a UIView. I Applied CATransform3D to change the Perspective of the UIView. When I change the Values, it works properly and changes the Perspective View of the UIView. But when I try to Save the Image It goes to it's default position.
Here is the Code
Transformation
func transformation ()
{
var transform = CATransform3DIdentity;
transform.m34 = 1.0 / -200
transform = CATransform3DRotate(transform, CGFloat(sliderX.value), 0, 1, 0)
transform = CATransform3DRotate(transform, CGFloat(sliderY.value), 1, 0, 0)
textStickerView.currentlyEditingLabel.layer.transform = transform
}
Saving Function
var imgSize = CGSize(width: mainImageView.bounds.size.width, height: mainImageView.bounds.size.height)
UIGraphicsBeginImageContextWithOptions(imgSize, false, UIScreen.main.scale)
mainImageView.addSubview(textStickerView)
mainImageView.layer.render(in: UIGraphicsGetCurrentContext()!)
let rowImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Use drawHierarchy(in: bounds, afterScreenUpdates: true) instead of mainImageView.layer.render(in: UIGraphicsGetCurrentContext()!)
extension UIView {
func asImage() -> UIImage {
if #available(iOS 10.0, *) {
let format = UIGraphicsImageRendererFormat()
format.opaque = isOpaque
format.scale = 1.0
let renderer = UIGraphicsImageRenderer(bounds: bounds, format: format)
return renderer.image { rendererContext in
//layer.render(in: rendererContext.cgContext) // can not save transform3D
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
} else {
UIGraphicsBeginImageContextWithOptions(bounds.size, true, 1.0)
//self.layer.render(in:UIGraphicsGetCurrentContext()!) // can not save transform3D
drawHierarchy(in: frame, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image ?? UIImage()
}
}
}
I have a UIScrollView as subview of a view controller main view. I'm trying to save a screenshot of whatever is visible in the frame of the UIScrollView only.
UIGraphicsBeginImageContextWithOptions(imageScrollView.bounds.size, false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: 0, y: 0)
view.layer.render(in: context!)
let visibleScrollViewImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let popupImageView = UIImageView(image: visibleScrollViewImage)
popupImageView.layer.borderColor = UIColor.white.cgColor
popupImageView.layer.borderWidth = 4
popupImageView.frame = CGRect(origin: CGPoint(x: 0, y: 400), size: CGSize(width: 400, height: 400))
imageScrollView.removeFromSuperview()
view.addSubview(popupImageView)
The part with the popupImageView is just to test out and see what is actually saving, it seems there is some offset problem, the horizontal axis is fine but i seem to be getting just the top third of the image I want, and above that is just dark space.
Seems like it must be a pretty easy solution but I've searched through all similar questions and can't find an answers.
Thanks heaps!
Try the following. If I do it with a UITableView control, it works.
import UIKit
class ViewController: UIViewController {
#IBAction func snapTapped(_ sender: UIButton) {
UIGraphicsBeginImageContextWithOptions(imageScrollView.bounds.size, true, 1.0)
imageScrollView.drawHierarchy(in: CGRect(origin: CGPoint.zero, size: imageScrollView.bounds.size), afterScreenUpdates: true)
if let image = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
myImageView.image = image
}
}
}
func screenShotMethod()->UIImage
{
let layer = self.imageScrollView.layer
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot!
}