【问题标题】:Slicing up a UIImage on iPhone在 iPhone 上切片 UIImage
【发布时间】:2008-10-29 22:28:56
【问题描述】:

目标:取一个UIImage,在中间裁剪出一个正方形,将正方形的大小改为320x320像素,将图像切成16张80x80的图像,将16张图像保存在一个数组中。

这是我的代码:

CGImageRef originalImage, resizedImage, finalImage, tmp;
float imgWidth, imgHeight, diff;
UIImage *squareImage, *playImage;
NSMutableArray *tileImgArray;
int r, c;

originalImage = [image CGImage];

imgWidth = image.size.width;
imgHeight = image.size.height;
diff = fabs(imgWidth - imgHeight);

if(imgWidth > imgHeight){
    resizedImage = CGImageCreateWithImageInRect(originalImage, CGRectMake(floor(diff/2), 0, imgHeight, imgHeight));
}else{
    resizedImage = CGImageCreateWithImageInRect(originalImage, CGRectMake(0, floor(diff/2), imgWidth, imgWidth));
}
CGImageRelease(originalImage);

squareImage = [UIImage imageWithCGImage:resizedImage];      
if(squareImage.size.width != squareImage.size.height){
    NSLog(@"image cutout error!");
    //*code to return to main menu of app, irrelevant here
}else{
    float newDim = squareImage.size.width;
    if(newDim != 320.0){
        CGSize finalSize = CGSizeMake(320.0, 320.0);
        UIGraphicsBeginImageContext(finalSize);
        [squareImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)];
        playImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }else{
        playImage = squareImage;
    }
}

finalImage = [playImage CGImage];
tileImgArray = [NSMutableArray arrayWithCapacity:0];
for(int i = 0; i < 16; i++){
    r = i/4;
    c = i%4;
    //*
    tmp = CGImageCreateWithImageInRect(finalImage, CGRectMake(c*tileSize, r*tileSize, tileSize, tileSize));
    [tileImgArray addObject:[UIImage imageWithCGImage:tmp]];
}

当原始(可变图像)的较小尺寸大于或小于 320 像素时,代码可以正常工作。当它正好是 320 时,生成的 80x80 图像几乎全是黑色的,有些边缘有几个像素(我不能确定)来自原始图像。

我通过直接显示完整图像进行测试:

[UIImage imageWithCGImage:finalImage];

间接地:

[UIImage imageWithCGImage:CGImageCreateWithImageInRect(finalImage, CGRectMake(0, 0, 320, 320))];

在这两种情况下,显示都有效。只有当我尝试切出图像的某些部分时才会出现问题。

【问题讨论】:

    标签: iphone objective-c cocoa-touch image-manipulation


    【解决方案1】:

    经过更多的实验,我找到了以下解决方案(但我仍然不知道为什么它没有像最初写的那样工作。)但是无论如何,即使在调整大小时,在调整大小代码到位后切片仍然有效是不必要的:

    if(newDim != 320.0){
                CGSize finalSize = CGSizeMake(320.0, 320.0);
                UIGraphicsBeginImageContext(finalSize);
                [squareImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)];
                playImage = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
    }else{
                CGSize finalSize = CGSizeMake(320.0, 320.0);
                UIGraphicsBeginImageContext(finalSize);
                [squareImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)];
                playImage = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
    }
    

    有人知道为什么会这样吗?

    附:是的,这里不再需要 if/else。 之前删除它,但我知道它会起作用是愚蠢的。

    【讨论】:

      【解决方案2】:

      只是出于好奇,当你知道要在其中放入 16 个东西时,为什么还要将可变数组的边界设为 0?

      嗯,除此之外,我已经尝试了您用于调整大小和切片的基本技术(我不需要裁剪,因为我正在处理已经是方形的图像)并且我无法重现您的模拟器中的问题。您可能想尝试将代码分成三个单独的函数(裁剪为正方形、调整大小和切片),然后分别测试这三个函数,以便找出三个步骤中的哪一个导致问题(即输入图像您已经在普通的图形程序中进行操作,而不是使用目标 c,然后检查您得到的结果!)。

      我将在下面附上我的调整大小和切片功能版本,希望对您有所帮助。很高兴看到你的版本,因为我不必一次就自己找到所有的方法。 :)

      请注意,这里提到的二维数组是我自己用 NSMutableArrays 构建的类,但您可以轻松实现自己的版本或使用平面 NSMutableArray。 ;)

      // cut the given image into a grid of equally sized smaller images
      // this assumes that the image can be equally divided in the requested increments
      // the images will be stored in the return array in [row][column] order
      + (TwoDimensionalArray *) chopImageIntoGrid : (UIImage *) originalImage : (int) numberOfRows : (int) numberOfColumns
      {   
      // figure out the size of our tiles
      int tileWidth = originalImage.size.width / numberOfColumns;
      int tileHeight = originalImage.size.height / numberOfRows;
      
      // create our return array
      TwoDimensionalArray * toReturn = [[TwoDimensionalArray alloc] initWithBounds : numberOfRows 
                                                                                   : numberOfColumns];
      
      // get a CGI image version of our image
      CGImageRef cgVersionOfOriginal = [originalImage CGImage];
      
      // loop to chop up each row
      for(int row = 0; row < numberOfRows ; row++){
          // loop to chop up each individual piece by column
          for (int column = 0; column < numberOfColumns; column++)
          {
              CGImageRef tempImage = 
                      CGImageCreateWithImageInRect(cgVersionOfOriginal, 
                                                   CGRectMake(column * tileWidth, 
                                                              row * tileHeight, 
                                                              tileWidth, 
                                                              tileHeight));
              [toReturn setObjectAt : row : column : [UIImage imageWithCGImage:tempImage]];
          }
      }
      
      // now return the set of images we created
      return [toReturn autorelease];
      }
      
      // this method resizes an image to the requested dimentions
      // be a bit careful when using this method, since the resize will not respect
      // the proportions of the image
      + (UIImage *) resize : (UIImage *) originalImage : (int) newWidth : (int) newHeight
      {   
      // translate the image to the new size
      CGSize newSize = CGSizeMake(newWidth, newHeight); // the new size we want the image to be
      UIGraphicsBeginImageContext(newSize); // downside: this can't go on a background thread, I'm told
      [originalImage drawInRect : CGRectMake(0, 0, newSize.width, newSize.height)];
      UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); // get our new image
      UIGraphicsEndImageContext();
      
      // return our brand new image
      return newImage;
      }
      

      伊娃·希弗

      【讨论】:

        猜你喜欢
        • 2011-07-19
        • 1970-01-01
        • 2021-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多