ios - proceso - tipos de descripcion pdf
Encontrar el cuadrado centrado más grande de un paisaje o un UII de retrato y escalarlo a un tamaño (2)
Necesito encontrar el cuadrado centrado más grande a partir de un retrato o una imagen de paisaje a escala. Por ejemplo, si obtengo una imagen de tamaño 1200x800 y necesito obtener el cuadrado centrado hasta el tamaño de 300x300.
Encontré una respuesta sobre esta pregunta en que ha sido ampliamente copiada. Sin embargo, esa respuesta es incorrecta, así que quiero publicar la respuesta correcta, que es la siguiente:
+ (UIImage*) cropBiggestCenteredSquareImageFromImage:(UIImage*)image withSide:(CGFloat)side
{
// Get size of current image
CGSize size = [image size];
if( size.width == size.height && size.width == side){
return image;
}
CGSize newSize = CGSizeMake(side, side);
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.height / image.size.height;
delta = ratio*(image.size.width - image.size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = newSize.width / image.size.width;
delta = ratio*(image.size.height - image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x, -offset.y,
(ratio * image.size.width),
(ratio * image.size.height));
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
La respuesta incorrecta que encontré antes es la siguiente:
+ (UIImage*) cropBiggestCenteredSquareImageFromImage:(UIImage*)image withSide:(CGFloat)side
{
// Get size of current image
CGSize size = [image size];
if( size.width == size.height && size.width == side){
return image;
}
CGSize newSize = CGSizeMake(side, side);
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.width / image.size.width;
delta = (ratio*image.size.width - ratio*image.size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = newSize.width / image.size.height;
delta = (ratio*image.size.height - ratio*image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x, -offset.y,
(ratio * image.size.width) + delta,
(ratio * image.size.height) + delta);
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
El problema con este código es que no se recorta correctamente.
Ambos códigos se pueden probar en la siguiente imagen: https://s3.amazonaws.com/anandprakash/ImageWithPixelGrid.jpg
Corregir Algo genera la siguiente imagen en la url base anterior: https://s3.amazonaws.com/anandprakash/ScreenshotCorrectAlgo.png
Wrong Algo genera la siguiente imagen en la url base anterior: fíjate en los 50 píxeles adicionales en el ancho de cada lado. https://s3.amazonaws.com/anandprakash/ScreenshotWrongAlgo.png
La misma respuesta anterior que una extensión Swift en UIImage:
private extension UIImage {
func cropBiggestCenteredSquareImage(withSide side: CGFloat) -> UIImage {
if self.size.height == side && self.size.width == side {
return self
}
let newSize = CGSizeMake(side, side)
let ratio: CGFloat
let delta: CGFloat
let offset: CGPoint
if self.size.width > self.size.height {
ratio = newSize.height / self.size.height
delta = ratio * (self.size.width - self.size.height)
offset = CGPointMake(delta / 2, 0)
}
else {
ratio = newSize.width / self.size.width
delta = ratio * (self.size.height - self.size.width)
offset = CGPointMake(0, delta / 2)
}
let clipRect = CGRectMake(-offset.x, -offset.y, ratio * self.size.width, ratio * self.size.height)
if UIScreen.mainScreen().respondsToSelector(#selector(NSDecimalNumberBehaviors.scale)) {
UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0)
} else {
UIGraphicsBeginImageContext(newSize);
}
UIRectClip(clipRect)
self.drawInRect(clipRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}