Home > Enterprise >  UIImage is rotated 90 degrees when creating from url and set to the pasteboard
UIImage is rotated 90 degrees when creating from url and set to the pasteboard

Time:02-13

What do I simply do?

let pasteboard = UIPasteboard.general
let base64EncodedImageString = "here_base_64_string_image"
let data = Data(base64Encoded: base64EncodedImageString)
let url = data?.write(withName: "image.jpeg")
pasteboard.image = UIImage(url: url) //and now when I try to paste somewhere that image for example in imessage, it is rotated... why?

What may be important:

  1. It happens only for images created by camera.
  2. However, if use exactly the same process (!) to create activityItems for UIActivityViewController and try to use iMessage app, then it works... why? What makes the difference?

I use above two simple extensions for UIImage and Data:

extension Data {
    func write(withName name: String) -> URL {
        let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(name)
        do {
            try write(to: url, options: NSData.WritingOptions.atomic)
            return url
        } catch {
            return url
        }
    }
}

extension UIImage {
    convenience init?(url: URL?) {
        guard let url = url else {
            return nil
        }
        do {
            self.init(data: try Data(contentsOf: url))
        } catch {
            return nil
        }
    }
}

Before server returns base64EncodedString I upload an image from camera like this:

func imagePickerController(
    _ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]
) {
    let image = info[.originalImage] as? UIImage
    let encodedBase64 = image?.jpegData(compressionQuality: 0.9)?.base64EncodedString() ?? ""
    //upload encodedBase64 to the server... that is all
}

CodePudding user response:

I am not sure but I think UIPasteBoard converts your image to PNG and discards its orientation. You can explicitly tell the kind of data you are adding to the pasteboard but I am not sure if this would work for your scenery.

extension Data {
    var image: UIImage? { UIImage(data: self) }
}

setting your pasteboard data

UIPasteboard.general.setData(jpegData, forPasteboardType: "public.jpeg")

loading the data from pasteboard

if let pbImage = UIPasteboard.general.data(forPasteboardType: "public.jpeg")?.image {

}

Or Redrawing your image before setting your pasteboard image property

extension UIImage {
    func flattened(isOpaque: Bool = true) -> UIImage? {
        if imageOrientation == .up { return self }
        UIGraphicsBeginImageContextWithOptions(size, isOpaque, scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(origin: .zero, size: size))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

UIPasteboard.general.image = image.flattened()
  • Related