Pasteboard UIImage not using scale

一个人想着一个人 提交于 2019-12-22 17:49:58

问题


I am building a custom keyboard and am having trouble adding an image to the pasteboard and maintaining the appropriate scale and resolution with in the pasted image. Let me start with a screenshot of the keyboard to illustrate my trouble:

So the picture of the face in the top left of the keyboard is just a UIButton with the original photo set to the background. When the button is pressed the image is resized with the following function:

func imageResize(image:UIImage, size:CGSize)-> UIImage {

    let scale  = UIScreen.mainScreen().scale

    UIGraphicsBeginImageContextWithOptions(size, false, scale)
    var context = UIGraphicsGetCurrentContext()

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh)
    image.drawInRect(CGRect(origin: CGPointZero, size: size))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return scaledImage
}

This function creates a UIImage the same size as the UIButton with the appropriate scale to reflect the device's screen resolution. To verify that the function is correct, I added an UIImageView filled with the scaled image. The scaled image is the image that looks misplaced near the center of the keyboard. I added the UIImageView with this function:

func addImageToBottomRight(image: UIImage) {
    var tempImgView = UIImageView(image: image)
    self.view.addSubview(tempImgView)
    tempImgView.frame.offset(dx: 100.0, dy: 50.0)
}

I have tried a few different methods for adding the image to the pasteboard, but all seem to ignore the scale of the image and display it twice as large as opposed to displaying it at a higher resolution:

let pb = UIPasteboard.generalPasteboard()!

var pngType = UIPasteboardTypeListImage[0] as! String
var jpegType = UIPasteboardTypeListImage[2] as! String

pb.image = image
pb.setData(UIImagePNGRepresentation(image), forPasteboardType: pngType)
pb.setData(UIImageJPEGRepresentation(image, 1.0), forPasteboardType: jpegType)

All three of these methods do not work correctly and produce the same result as illustrated in the screenshot. Does anyone have any suggestions of other methods? To further clarify my goal, I would like the image in the message text box to look identical to both UIImages in the keyboard in terms of size and resolution.

Here are a few properties of the UIImage before and resize in case anyone is curious:

Starting Image Size is (750.0, 750.0)
Size to scale to is: (78.0, 78.0))
Initial Scale: 1.0

Resized Image Size is (78.0, 78.0)
Resized Image Scale: 2.0

回答1:


I know this is an old post, but thought I share the work around I found for this specific case of copying images and pasting to messaging apps.The thing is, when you send a picture with such apps like iMessages, whatsapp, messenger, etc, the way they display the image is so that it aspect fits to some certain horizontal width (lets say around 260 pts for this demo).

As you can see from the diagram below, if you send 150x150 image @1x resolution in imessage, it will be stretched and displayed in the required 260 width box, making the image grainy.

But if you add an empty margin of width 185 to both the left and right sides of the image, you will end up with an image of size 520x150. Now if you send that sized image in imessage, it will have to fit it in a 260 width box, ending up cramming a 520x150 image in a 260x75 box, in a way giving you a 75x75 image at @2x resolution.

You can add a clear color margin to a UIImage with a code like this

extension UIImage {
    func addMargin(withInsets inset: UIEdgeInsets) -> UIImage? {
         let finalSize = CGSize(width: size.width + inset.left + inset.right, height: size.height + inset.top + inset.bottom)
         let finalRect = CGRect(origin: CGPoint(x: 0, y: 0), size: finalSize)

            UIGraphicsBeginImageContextWithOptions(finalSize, false, scale)
            UIColor.clear.setFill()
            UIGraphicsGetCurrentContext()?.fill(finalRect)

            let pictureOrigin = CGPoint(x: inset.left, y: inset.top)
            let pictureRect = CGRect(origin: pictureOrigin, size: size)

            draw(in: pictureRect)
            let finalImage = UIGraphicsGetImageFromCurrentImageContext()
            defer { UIGraphicsEndImageContext() }

            return finalImage
 }

}



来源:https://stackoverflow.com/questions/32385095/pasteboard-uiimage-not-using-scale

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!