【发布时间】:2012-05-20 10:39:46
【问题描述】:
我们试图做的基本想法是我们有一个很大的 UIImage,我们想把它分成几块。该函数的用户可以传入行数和列数,图像将被相应地裁剪(即3行3列将图像切成9块)。问题是,我们在尝试使用 CoreGraphics 完成此操作时遇到了性能问题。我们需要的最大网格是 5x5,操作需要几秒钟才能完成(这对用户来说是滞后时间)。这当然远非最佳。
我和我的同事在这方面花了很长时间,并在网上搜索了答案,但没有成功。我们俩都没有在 Core Graphics 方面非常有经验,所以我希望代码中有一些愚蠢的错误可以解决我们的问题。 SO用户,请您帮助我们解决这个问题!
我们使用http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/ 的教程来修改我们的代码。
下面的函数:
-(void) getImagesFromImage:(UIImage*)image withRow:(NSInteger)rows withColumn:(NSInteger)columns
{
CGSize imageSize = image.size;
CGFloat xPos = 0.0;
CGFloat yPos = 0.0;
CGFloat width = imageSize.width / columns;
CGFloat height = imageSize.height / rows;
int imageCounter = 0;
//create a context to do our clipping in
UIGraphicsBeginImageContext(CGSizeMake(width, height));
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGRect clippedRect = CGRectMake(0, 0, width, height);
CGContextClipToRect(currentContext, clippedRect);
for(int i = 0; i < rows; i++)
{
xPos = 0.0;
for(int j = 0; j < columns; j++)
{
//create a rect with the size we want to crop the image to
//the X and Y here are zero so we start at the beginning of our
//newly created context
CGRect rect = CGRectMake(xPos, yPos, width, height);
//create a rect equivalent to the full size of the image
//offset the rect by the X and Y we want to start the crop
//from in order to cut off anything before them
CGRect drawRect = CGRectMake(rect.origin.x * -1,
rect.origin.y * -1,
image.size.width,
image.size.height);
//draw the image to our clipped context using our offset rect
CGContextDrawImage(currentContext, drawRect, image.CGImage);
//pull the image from our cropped context
UIImage* croppedImg = UIGraphicsGetImageFromCurrentImageContext();
//PuzzlePiece is a UIView subclass
PuzzlePiece* newPP = [[PuzzlePiece alloc] initWithImageAndFrameAndID:croppedImg :rect :imageCounter];
[slicedImages addObject:newPP];
imageCounter++;
xPos += (width);
}
yPos += (height);
}
//pop the context to get back to the default
UIGraphicsEndImageContext();
}
非常感谢任何建议!
【问题讨论】:
-
您是将图像保存在某处还是仅在屏幕上以 5x5 不同的视图向用户显示它们?如果您只显示它们,那么在每个视图中设置整个图像(它仍然只是内存中的一个图像)然后为每个 UIImageView 偏移它可能会更有效,这样每个视图中只有正确的部分可见。跨度>
-
@DavidRönnqvist 我们只是显示它们,而不是保存它们。您的答案听起来像是一个更有效的解决方案!我从来没有尝试过在 UIImageView 中偏移 UIImage——我只使用了 initWithImage 和 setImage 来设置图像本身,之后再也没玩过它。你是怎样做的?虽然我想——我可以使用带有 clipsToBounds = true 的常规 UIView,添加一个 UIImageView 作为子视图,并将 UIImageView 偏移任何必要的量?
-
@DavidRönnqvist 我对你建议的变体——使用 UIView/clipsToBounds/UIImageView 作为子视图——就像一个魅力!如果您发布一个答案,详细说明您的原始建议,我很乐意接受它:) 非常感谢 - 这一直困扰着我!
-
@DavidRönnqvist - 我不太确定你在内存中只有一个图像副本。这些视图中的每一个都应该在幕后保存一个单独的未压缩版本的图像(每像素 4 字节),我认为如果您在 Memory Monitor 工具中查看应用程序的真实大小,您会看到它。
-
@BradLarson 嗯,在这种情况下,这肯定不是一个内存效率高的解决方案。您对我们可以做的不占用大量内存且运行效率高的事情有什么想法吗?谢谢!
标签: ios uikit uiimage core-graphics crop