从风景或肖像UIImage中找到最大的居中方块并将其缩放到一个大小

And*_*y P 3 crop uiimage ios

我需要从缩放到大小的肖像或风景图像中找到最大的居中方块.例如,如果我得到尺寸为1200x800的图像,我需要将居中的正方形缩小到300x300.

And*_*y P 15

我在stackoverflow上找到了关于这个问题的答案,这个问题已被广泛复制.但是答案不正确,所以想要发布正确的答案如下:

+ (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;
}
Run Code Online (Sandbox Code Playgroud)

我之前找到的错误答案如下:

+ (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;
}
Run Code Online (Sandbox Code Playgroud)

此代码的问题在于它无法正确裁剪.

这两个代码都可以在以下图片中试用:https: //s3.amazonaws.com/anandprakash/ImageWithPixelGrid.jpg

正确的Algo会在上面的基本网址上生成以下图片:https: //s3.amazonaws.com/anandprakash/ScreenshotCorrectAlgo.png

错误的Algo会在上面的基本网址上生成以下图片 - 请注意每边宽度的额外50px. https://s3.amazonaws.com/anandprakash/ScreenshotWrongAlgo.png