objective animatedimage ios uiimageview uiimage

ios - animatedimage - Cómo recortar un UIImageView a un nuevo UIImage en modo ''ajuste de aspecto''?



objective c uiimage (4)

Me gustaría crear un nuevo UIImage recortando la imagen dentro de UIImageView. Por ejemplo, en la imagen de arriba, quiero un nuevo UIImage del área delineada en verde. Encontré código para hacer esto, normalmente se ve algo así (como una categoría de UIImage):

- (UIImage *)croppedImage:(CGRect)bounds { CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds); UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); return croppedImage; }

Tiene mucho sentido. SIN EMBARGO, mi UIImageView está en contentMode ''aspect fit''. Parece que eso complica los cálculos de CGRect para CGImageCreateWithImageInRect y no he podido encontrar la solución adecuada.

Me imagino que necesito aplicar las mismas transformaciones al rect verde que se hicieron a la imagen?

TAMBIÉN: encontré esta otra pregunta aquí ( Cómo saber el tamaño de la imagen después de aplicar el aspecto adecuado para la imagen en un UIImageView ), que parece mostrar una forma de fuerza bruta de obtener el tamaño, pero todavía no estoy seguro de cómo encaja eso en una situación de cultivo.

¿Algunas ideas?

EDITAR : En mi caso, literalmente tengo un cuadrado como se muestra arriba dibujado en una vista de superposición sobre el UIImageView. Entonces, mientras me doy cuenta de que estoy recortando el UIImage (dentro de UIImageView), necesito de alguna manera cambiar el CGRect verde para que ''coincida'' con la transformación realizada cuando se aplica ''aspect fit''. Por ejemplo, si dejo mi UIImageView en el modo ''arriba a la izquierda'', todo funciona bien, porque hay un mapeo 1: 1 entre el UIImage subyacente y el UIImageView. El problema en el modo ''arriba a la izquierda'' es que la imagen completa no siempre se muestra, porque podría ser más grande que mi UIImageView.


Creo que no entiendes lo que estás haciendo. No puedes "cortar" un UIImageView, solo UIImages. Por lo tanto, su método de imagen recortada debería estar en una categoría UIImage y no en una categoría UIImageView. Los límites rect que pase al método de recorte deben estar relacionados con el tamaño de la imagen, no con los límites de la vista de la imagen. Es irrelevante cuál es el contentMode de la vista de la imagen: el recorte de la imagen siempre funcionará de la misma manera. Primero obtén la imagen de la vista de la imagen. Luego, cree una nueva imagen recortada y finalmente configure la imagen recortada para la vista de la imagen. Esto se puede hacer en una línea de código:

imageView.image = [imageView.image croppedImage:rect];

Dado que su modo de contenido es ''aspecto adecuado'', la nueva imagen se estirará automáticamente para caber en el marco de la vista. También puede intentar cambiar el marco de visualización según el tamaño de la imagen para evitar efectos de pixelación.


Sé que la respuesta ha sido, pero he tenido algunos problemas para ir arriba, así que tampoco publicaré mi solución.

El problema es que la imagen tiene una escala con un aspecto adecuado, pero conocemos el factor de escala tanto para el ancho como para la altura. Entonces podemos calcular el rectángulo de recorte correcto bastante fácil:

-(UIImage*)crop:(CGRect)frame { // Find the scalefactors UIImageView''s widht and height / UIImage width and height CGFloat widthScale = self.bounds.size.width / self.image.size.width; CGFloat heightScale = self.bounds.size.height / self.image.size.height; // Calculate the right crop rectangle frame.origin.x = frame.origin.x * (1 / widthScale); frame.origin.y = frame.origin.y * (1 / heightScale); frame.size.width = frame.size.width * (1 / widthScale); frame.size.height = frame.size.height * (1 / heightScale); // Create a new UIImage CGImageRef imageRef = CGImageCreateWithImageInRect(self.image.CGImage, frame); UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); return croppedImage; }


Yo uso el método a continuación.

-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect { CGSize cropSize = rect.size; CGFloat widthScale = image.size.width/self.imageViewOriginal.bounds.size.width; CGFloat heightScale = image.size.height/self.imageViewOriginal.bounds.size.height; cropSize = CGSizeMake(rect.size.width*widthScale, rect.size.height*heightScale); CGPoint pointCrop = CGPointMake(rect.origin.x*widthScale, rect.origin.y*heightScale); rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, cropSize.height); CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect); UIImage *croppedImage = [UIImage imageWithCGImage:subImage]; CGImageRelease(subImage); return croppedImage; }


Basado en mi otra respuesta a una pregunta similar, he escrito este método para una categoría de UIImageView:

-(CGRect) cropRectForFrame:(CGRect)frame { NSAssert(self.contentMode == UIViewContentModeScaleAspectFit, @"content mode must be aspect fit"); CGFloat widthScale = self.bounds.size.width / self.image.size.width; CGFloat heightScale = self.bounds.size.height / self.image.size.height; float x, y, w, h, offset; if (widthScale<heightScale) { offset = (self.bounds.size.height - (self.image.size.height*widthScale))/2; x = frame.origin.x / widthScale; y = (frame.origin.y-offset) / widthScale; w = frame.size.width / widthScale; h = frame.size.height / widthScale; } else { offset = (self.bounds.size.width - (self.image.size.width*heightScale))/2; x = (frame.origin.x-offset) / heightScale; y = frame.origin.y / heightScale; w = frame.size.width / heightScale; h = frame.size.height / heightScale; } return CGRectMake(x, y, w, h); }

Puede pasar en el marco de su rect verde (suponiendo que sea una vista secundaria de la vista de la imagen) y recuperar el recorte para recortar el UIImage. ¡Tenga en cuenta que solo funciona para el modo ''ajuste de aspecto''! Aunque no lo he probado. Entonces, dime si funciona