在iPhone上切割UIImage

13

目标:获取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]];
}

当原图(image变量)的较小维度大于或小于320像素时,代码可以正常工作。但是当它恰好为320像素时,生成的80x80图像几乎全部是黑色的,有些边缘的像素可能(我无法确定)来自原始图像。

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

[UIImage imageWithCGImage:finalImage];

间接地:

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

在这两种情况下,显示器都能正常工作。问题只在我试图切出图像的某一部分时才会出现。

2个回答

5
经过进一步试验,我找到了以下解决方案(尽管我仍然不知道为什么最初的代码没有起作用)。但无论如何,在调整大小不必要时,放置调整大小代码后切片仍能正常工作。
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();
}

有人知道为什么会发生这种情况吗?

P.S. 是的,如果/否则在这里不再需要。在我知道它会起作用之前移除它是愚蠢的,但现在可以移除。


1

只是出于好奇,当你知道你要放16个东西时,为什么要用0的边界来制作可变数组呢?

除此之外,我尝试了你用于调整大小和切片的基本技术(因为我正在使用已经是正方形的图像,所以我不需要裁剪),并且我无法在模拟器中重现你的问题。你可能想要将你的代码分成三个单独的函数(裁剪成正方形、调整大小和切片成块),然后分别测试这三个函数,这样你就可以找出哪一个步骤导致了问题(例如,输入的图像是你在普通图形程序中操作过的,而不是使用Objective 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;
}

伊娃·席费尔


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接