【问题标题】:Create a sub-image from a larger image从较大的图像创建子图像
【发布时间】:2012-05-20 13:07:46
【问题描述】:

从 REST 端点传输大图像后,我需要将图像分成多个较小的图像块。

初始图像(例如)1024x1024,存储在 NSData 中;我需要创建大小为 256x256 的子图像(在这种情况下,将有 16 个子图像)。

如何做到这一点? (我还没有找到任何接近的文章,但我认为这一定是可能的,因为大多数图像编辑软件都支持图像裁剪。)

谢谢。

【问题讨论】:

    标签: objective-c ios jpeg


    【解决方案1】:

    这是我在某些项目中用来裁剪图像的功能。

    - (UIImage *)cropImage:(UIImage *) image{
       CGRect rect = CGRectMake(0, 0, 256, 256);
       CGImageRef subImageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
       CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));
    
       UIGraphicsBeginImageContext(smallBounds.size);
       CGContextRef context = UIGraphicsGetCurrentContext();
       CGContextDrawImage(context, smallBounds, subImageRef);
       UIImage* smallImg = [UIImage imageWithCGImage:subImageRef];
       UIGraphicsEndImageContext();
    
       return smallImg;
    }
    

    我认为你可以从那里多次调用它来裁剪你的图片 16 次。

    希望对你有帮助

    【讨论】:

    • 我认为您还需要手动释放 CGImageRef(就像您自己创建的那样):CGImageRelease(subImageRef);
    【解决方案2】:

    originalImageView 是一个 IBOutlet ImageView。此图像将被裁剪。

    #import <QuartzCore/QuartzCore.h>
    

    每个切片周围的边框都需要这样做,以便更好地理解。

    -(UIImage*)getCropImage:(CGRect)cropRect
    {
    CGImageRef image = CGImageCreateWithImageInRect([originalImageView.image CGImage],cropRect);
    UIImage *cropedImage = [UIImage imageWithCGImage:image];
    CGImageRelease(image);
    return cropedImage;
    }
    
    -(void)prepareSlices:(uint)row:(uint)col
    {
    float flagX = originalImageView.image.size.width / originalImageView.frame.size.width;
    float flagY = originalImageView.image.size.height / originalImageView.frame.size.height;
    
    float _width    = originalImageView.frame.size.width / col;
    float _height   = originalImageView.frame.size.height / row;
    
    float _posX = 0.0;
    float _posY = 0.0;
    
    for (int i = 1; i <= row * col; i++) {
    
        UIImageView *croppedImageVeiw = [[UIImageView alloc] initWithFrame:CGRectMake(_posX, _posY, _width, _height)];
        UIImage *img = [self getCropImage:CGRectMake(_posX * flagX,_posY * flagY, _width * flagX, _height * flagY)];
        croppedImageVeiw.image = img;
    
        croppedImageVeiw.layer.borderColor = [[UIColor whiteColor] CGColor];
        croppedImageVeiw.layer.borderWidth = 1.0f;
    
        [self.view addSubview:croppedImageVeiw];
        [croppedImageVeiw release];
    
        _posX += _width;
    
        if (i % col == 0) {
            _posX = 0;
            _posY += _height;
        }
    
    }
    
    originalImageView.alpha = 0.0;
    
    }
    

    这样称呼它:

    [self prepareSlices:16 :16];
    

    【讨论】:

      【解决方案3】:
      @interface UIImage (Sprite)
      - (NSArray *)spritesWithSpriteSheetImage:(UIImage *)image spriteSize:(CGSize)size;
      - (NSArray *)spritesWithSpriteSheetImage:(UIImage *)image inRange:(NSRange)range spriteSize:(CGSize)size;
      @end
      
      
      
      
      @implementation UIImage (Sprite)
      
      -(NSArray *)spritesWithSpriteSheetImage:(UIImage *)image spriteSize:(CGSize)size {
          return [self spritesWithSpriteSheetImage:self inRange:NSMakeRange(0, lroundf(MAXFLOAT)) 
                                    spriteSize:size];
      }
      -(NSArray *)spritesWithSpriteSheetImage:(UIImage *)image 
                                  inRange:(NSRange)range 
                               spriteSize:(CGSize)size {
      if (!image || CGSizeEqualToSize(size, CGSizeZero) || range.length == 0) 
          return nil;
      NSLog(@"%i %i", range.location, range.length);
      CGImageRef spriteSheet = [image CGImage];
      NSMutableArray *tempArray = [[[NSMutableArray alloc] init] autorelease];
      
      int width = CGImageGetWidth(spriteSheet);
      int height = CGImageGetHeight(spriteSheet);
      
      int maxI = width / size.width;
      int startI = 0;
      int startJ = 0;
      int length = 0;
      int startPosition = range.location;
      
      // Extracting initial I & J values from range info
      //
      if (startPosition != 0) {
          for (int k=1; k<=maxI; k++) {
              int d = k * maxI;
              if (d/startPosition == 1) {
                  startI = maxI - (d % startPosition);
                  break;
              }
              else if (d/startPosition > 1) {
                  startI = startPosition;
                  break;
              }
              startJ++;
          }
      }
      int positionX = startI * size.width;
      int positionY = startJ * size.height;
      BOOL isReady = NO;
      while (positionY < height) {
          while (positionX < width) {
              CGImageRef sprite = CGImageCreateWithImageInRect(spriteSheet, CGRectMake(positionX, positionY, size.width, size.height));
              [tempArray addObject:[UIImage imageWithCGImage:sprite]];
              CGImageRelease(sprite);
              length++;
              if (length == range.length) {
                  isReady = YES;
                  break;
              }
              positionX += size.width;
          }
          if (isReady) 
              break;
          positionX = 0;
          positionY += size.height;
      }
      return [NSArray arrayWithArray:tempArray];
        }
      @end
      

      【讨论】:

      • 我没有机会回到这个项目(很可能不会有很长一段时间),所以我还没有实施/测试答案。也就是说,我想给予信任,所以我将此答案标记为已接受。谢谢。
      猜你喜欢
      • 2011-07-03
      • 2014-10-29
      • 2017-09-03
      • 2012-07-05
      • 2020-09-26
      • 2016-04-26
      • 2023-03-29
      • 2010-09-22
      • 1970-01-01
      相关资源
      最近更新 更多