我的iPhone应用中的图像有问题。我按如下方式加载图像:
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:@""]];
CGImageRef imageRef = image.CGImage;
NSInteger texWidth = CGImageGetWidth(*imageRef);
NSInteger texHeight = CGImageGetHeight(*imageRef);
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
CGContextRef textureContext = CGBitmapContextCreate(textureData, texWidth, texHeight, 8,
texWidth * 4, CGImageGetColorSpace(*imageRef),
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth,
(float)texHeight), *imageRef);
CGContextRelease(textureContext);
glBindTexture(GL_TEXTURE_2D, location);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureData);
free(textureData);
我想释放图片使用的所有内存。我试着这样做:
CGImageRelease(imageRef);
free(image);
但是,根据Instruments,内存似乎没有被释放。我错过了什么吗?它是否被其中一个功能缓存?此外,当我稍后重新加载图像时,它似乎被加载两次,即alpha通道是第一次加载的两倍。而且,当我(尝试)释放内存并第三次重新加载时,alpha通道是第一次的三倍。应该几乎透明的部分变得越来越不透明。
iOS 3中没有注意到透明度的问题,只有iOS 4.但两者都注意到内存未被释放的问题。
请有人帮我这个吗?我花了很多时间搞乱图像!此外,我认为我没有使用愚蠢的图像:我正在制作一个使用大约40张图像的游戏,其中大多数是128x128 PNG。为什么我这么快就耗尽了内存?这种情况的“常见”做法是什么?在不需要图像时我是否正确地试图释放内存?
回复将不胜感激!谢谢。
答案 0 :(得分:1)
使用OpenGL时释放内存的答案很简单:http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml
与释放OpenGL使用的纹理相比,释放UIImage使用的内存几乎不可见。问题在于以下代码:
GLuint textures[100]; // allows total of 100 textures
location = textures[imageNo];
glBindTexture(GL_TEXTURE_2D, location);
它通过以下方式解决:
void unloadImage(GLuint imageNo)
{
[textureImages[imageNo] release];
glDeleteTextures(1, &textures[imageNo]);
}
我真的希望这对于在iPhone上使用OpenGL纹理的其他人来说非常有用,因为它让我在圈子中玩了很长时间!
感谢@sergio帮助解决了我的问题!
答案 1 :(得分:0)
我认为你应该这样做:
[image release];
而不是
CGImageRelease(imageRef);
实际上,您分配的对象是image
,然后您可以获得对其中一个成员的引用;您不需要释放对成员的引用,而是释放您分配的原始对象。您无需致电free(*image);
编辑:
*image
和*imageRef
的所有使用对我来说都不正确;您应该使用image
和imageRef
:
CGImageRef imageRef = image.CGImage;
NSInteger texWidth = CGImageGetWidth(imageRef);
NSInteger texHeight = CGImageGetHeight(imageRef);
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
CGContextRef textureContext = CGBitmapContextCreate(textureData, texWidth, texHeight, 8,
texWidth * 4, CGImageGetColorSpace(imageRef),
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth,
(float)texHeight), imageRef);
CGContextRelease(textureContext);
glBindTexture(GL_TEXTURE_2D, location);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureData);
free(textureData);
关于内存消耗:我认为使用OpenGLES框架可能会产生固定的损失,即增加应用程序的总内存占用量(由于加载框架并实例化我不知道哪些对象);但是每次绘制纹理时都不应该出现意外的内存增加。