目标:拍摄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))];
在这两种情况下,显示都有效。只有在我试图切出图像的某些部分时才会出现这些问题。
答案 0 :(得分: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。是的,如果此处不再需要/ else。在 之前删除它我知道它会起作用将是愚蠢的。
答案 1 :(得分:1)
出于好奇,当你知道你要把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;
}
Eva Schiffer