ios - 缩小图像复制到粘贴板后变得模糊 - Swift 3.0

标签 ios swift image imageview image-resizing

我正在捕获一个图像,然后将其放置在一个小 imageView 中。图片在小 imageView 中并不模糊,但是当我将其复制到剪贴板时,我正在调整图片大小,使其与 imageView 大小相同,但现在粘贴时它很模糊。

代码如下:

import UIKit
import AVFoundation

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    @IBOutlet weak var cameraView: UIView!
    @IBOutlet weak var imageView: UIImageView!

    var session: AVCaptureSession?
    var stillImageOutput: AVCaptureStillImageOutput?
    var videoPreviewLayer: AVCaptureVideoPreviewLayer?
    var captureDevice:AVCaptureDevice?
    var imagePicker: UIImagePickerController!

    override func viewDidLoad() {
        super.viewDidLoad()

        alignment()
        tapToCopy()
    }

    override func viewWillAppear(_ animated: Bool) {
        session = AVCaptureSession()
        session!.sessionPreset = AVCaptureSessionPresetPhoto

        let videoDevices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo)

        for device in videoDevices!{
            let device = device as! AVCaptureDevice
            if device.position == AVCaptureDevicePosition.front {
                captureDevice = device
            }
        }

        //We will make a new AVCaptureDeviceInput and attempt to associate it with our backCamera input device.
        //There is a chance that the input device might not be available, so we will set up a try catch to handle any potential errors we might encounter.
        var error: NSError?
        var input: AVCaptureDeviceInput!
        do {
            input = try AVCaptureDeviceInput(device: captureDevice)
        } catch let error1 as NSError {
            error = error1
            input = nil
            print(error!.localizedDescription)
        }

        if error == nil && session!.canAddInput(input) {
            session!.addInput(input)
            // ...
            // The remainder of the session setup will go here...

            stillImageOutput = AVCaptureStillImageOutput()
            stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]

            if session!.canAddOutput(stillImageOutput) {
                session!.addOutput(stillImageOutput)
                // ...
                // Configure the Live Preview here...

                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
                videoPreviewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
                videoPreviewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
                cameraView.layer.addSublayer(videoPreviewLayer!)
                session!.startRunning()
            }
        }
    }

    func alignment() {
        let height = view.bounds.size.height
        let width = view.bounds.size.width

        cameraView.bounds.size.height = height / 10
        cameraView.bounds.size.width = height / 10
        cameraView.layer.cornerRadius = height / 20

        imageView.bounds.size.height = height / 10
        imageView.bounds.size.width = height / 10
        imageView.layer.cornerRadius = height / 20
        imageView.clipsToBounds = true
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        videoPreviewLayer!.frame = cameraView.bounds
    }

    @IBAction func takePic(_ sender: Any) {
        if (stillImageOutput!.connection(withMediaType: AVMediaTypeVideo)) != nil {
            let videoConnection = stillImageOutput!.connection(withMediaType: AVMediaTypeVideo)
            // ...
            // Code for photo capture goes here...
            stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
                // ...
                // Process the image data (sampleBuffer) here to get an image file we can put in our captureImageView

                if sampleBuffer != nil {
                    let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                    let dataProvider = CGDataProvider(data: imageData as! CFData)
                    let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
                    let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.right)
                    // ...
                    // Add the image to captureImageView here...

                    self.imageView.image =  self.resizeImage(image: image, newHeight: self.view.bounds.size.height / 10)
                }
            })
        }
    }

    func tapToCopy() {
        let imageTap = UITapGestureRecognizer(target: self, action: #selector(self.copyToClipboard(recognizer:)))
        imageTap.numberOfTapsRequired = 1
        imageView.isUserInteractionEnabled = true
        imageView.addGestureRecognizer(imageTap)
    }

    func copyToClipboard(recognizer: UITapGestureRecognizer) {
        UIPasteboard.general.image = self.resizeImage(image: imageView.image!, newHeight: self.view.bounds.size.height / 10)
    }

    func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {
        let scale = newHeight / image.size.height
        let newWidth = image.size.width * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }
}

最佳答案

首先,你是说:

UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))

永远,永远,永远调用UIGraphicsBeginImageContext。就当它不存在吧。始终调用 UIGraphicsBeginImageContextWithOptions 来代替。它需要两个额外的参数,它们应该始终为 false0。当您进行更改时,情况会好很多,因为图像将包含您当前正在删除的比例信息。

另一个问题是,您连续两次调整同一图像的大小 - 一次是在 ImageView 中显示图像,然后当您从 ImageView 中拉出图像并将其放在粘贴板上时再次调整其大小。不要那样做!相反,存储原始图像,而不调整大小。稍后,您可以将放在粘贴板上 - 或调整原始图像的大小,这样您只需调整它一次大小,与 ImageView 中的图像完全分开。 p>

关于ios - 缩小图像复制到粘贴板后变得模糊 - Swift 3.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40825163/

相关文章:

android - 在 iOS 和 Android 上唯一标识 Beacon

ios - Adyen 支付 iOS 集成

swift - MacOS/OSx - 以编程方式更改 iTunes 库歌曲/项目上的元数据

ios - Swift:应用程序因 EXC_BAD_INSTRUCTION 错误而崩溃?

iphone - html img 标签中的图像在我的 iPhone 应用程序中变得模糊

ios - NSNotification postNotification 和 addObserver

objective-c - iOS – NSMutableArray 和 block 复制

swift - PaintCode NSButton 显示颠倒

Android相机位图内存泄漏

c++ - 使用 C++ 从多个网络摄像头捕获图片