Creé un nuevo archivo UIImage + compress.swift y está en el mismo directorio que mi PhotoController.swift. Estaba buscando formas de comprimir una imagen antes de almacenarla y encontré el siguiente enlace que explica el proceso: ¿Cómo comprimir o reducir el tamaño de una imagen antes de subirla a Parse como PFFile? (Swift)

Intenté llamar directamente a UIImageJPEGRepresentation para obtener la imagen, pero eso no me lleva a ningún lado. Intenté hacer público el método de extensión con la esperanza de resolver el problema, pero tampoco funcionó. Traté de buscar preguntas similares en stackOverflow, pero son diferentes porque ninguna explica por qué el método no es utilizable.

Este es el código para el método de extensión:

import UIKit

extension UIImage {
enum JPEGQuality: CGFloat {
    case lowest  = 0
    case low     = 0.25
    case medium  = 0.5
    case high    = 0.75
    case highest = 1
}

/// Returns the data for the specified image in JPEG format.
/// If the image object’s underlying image data has been purged, calling this function forces that data to be reloaded into memory.
/// - returns: A data object containing the JPEG data, or nil if there was a problem generating the data. This function may return nil if the image has no data or if the underlying CGImageRef contains data in an unsupported bitmap format.
func jpeg(_ jpegQuality: JPEGQuality) -> Data? {
    return UIImageJPEGRepresentation(self, jpegQuality.rawValue)
}

}

Este es el código para PhotoController donde trato de llamar al método de extensión:

class PhotoController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

... ...

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    let mediaType = info[UIImagePickerControllerMediaType] as! NSString



    if mediaType.isEqual(to: kUTTypeImage as String) {
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage

        var res = image.jpeg(.lowest) as! UIImage

        if (newMedia == true) {
            UIImageWriteToSavedPhotosAlbum(res,
                                           self,
                                           #selector(PhotoController.image(image:didFinishSavingWithError:contextInfo:)),
                                           nil)
            }
        }
        self.dismiss(animated: true, completion: nil)
    }

}

Sigo recibiendo el error: el valor del tipo 'UIImage' no tiene miembro 'comprimir'.

Además, ¿cómo imprimo el tamaño de la imagen para asegurarme de que está realmente comprimida?

-4
shiv 10 may. 2019 a las 21:15

5 respuestas

La mejor respuesta

Aquí le mostramos cómo hacer que su archivo Swift forme parte del objetivo, para que otro código pueda verlo.

Primero, haga clic en el proyecto, edite el objetivo de la aplicación y encuentre las Fases de compilación. Abra la sección de compilación de fuentes.

enter image description here

Haga clic en el botón Más en la parte inferior izquierda. Encuentra tu archivo y elígelo. (Si no lo ve en la lista, elija Agregar otro y encuéntrelo).

enter image description here

1
matt 10 may. 2019 a las 21:15

El método se llama jpeg(_:), no compress:

let imageData = image.jpeg(.lowest)

Dado que el valor de retorno es opcional, es posible que desee verificar:

guard let imageData = image.jpeg(.lowest) else { return }

Para obtener el tamaño en bytes, simplemente vea imageData.count.

0
Sulthan 10 may. 2019 a las 18:54

Todavía no sé por qué el método de extensión no funciona en un archivo separado. Intenté la sugerencia de @RajeshKumar R y la extensión funciona mientras todavía está en el archivo PhotoController.swift.

Después de usar la función .jpeg con la configuración más baja, el tamaño de la imagen se redujo de 14 MB a 14 MB.

 Image size: 13671.8408203125
 Compressed image size: 7796.853515625 

Aquí se explica cómo hacer que el código funcione.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    let mediaType = info[UIImagePickerControllerMediaType] as! NSString



    if mediaType.isEqual(to: kUTTypeImage as String) {
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        printImageSize(image: image)

        var imageData = image.jpeg(.lowest)

        let imageCompressed = UIImage(data: imageData!)
        printImageSize(image: imageCompressed!)

        if (newMedia == true) {
            UIImageWriteToSavedPhotosAlbum(imageCompressed!,
                                           self,
                                           #selector(PhotoController.image(image:didFinishSavingWithError:contextInfo:)),
                                           nil)
        }
    }
    self.dismiss(animated: true, completion: nil)
}
0
rmaddy 10 may. 2019 a las 20:37

Puede ser un error del compilador, pero no asigne la respuesta al mismo objeto UIImage ya que es del tipo Data

 let res = image.compress(.lowest)
0
Sh_Khan 10 may. 2019 a las 18:19

¿Dónde se declara el método 'comprimido' en su extensión? de acuerdo con su configuración, debe hacer esto ...

image.jpeg(.medium)
0
MXNMike 10 may. 2019 a las 18:51