Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何以正确的方式加载和卸载图像_Iphone_Image_Memory - Fatal编程技术网

Iphone 如何以正确的方式加载和卸载图像

Iphone 如何以正确的方式加载和卸载图像,iphone,image,memory,Iphone,Image,Memory,我在iPhone应用程序中处理图像时遇到困难。我按如下方式加载图像: UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:@""]]; CGImageRef imageRef = image.CGImage; NSInteger texWidth = CGImageGetWidth(*imageRef); NSInteger tex

我在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);
我想释放图像使用过的所有内存。我尝试这样做如下:

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);
然而,根据仪器,内存似乎没有被释放。我错过什么了吗?它是否由这些函数之一缓存?此外,当我稍后重新加载图像时,它似乎加载了两次,即alpha通道是第一次加载的两倍。同样,当我(试图)释放内存并再次重新加载时,alpha通道是第一次的三倍。原本应该几乎透明的部分正变得越来越不透明

在iOS 3中,只有iOS 4没有注意到透明度问题。但这两种方法都注意到了内存未被释放的问题

有人能帮我吗?我花了太多时间在图像上乱搞!另外,我不认为我使用了太多的图像:我正在制作一个使用大约40个图像的游戏,其中大部分是128x128 PNG。为什么我的内存这么快就用完了??这种情况下的“常见”做法是什么?当图像不需要时,我尝试释放内存对吗


回复将不胜感激!谢谢。

我认为你应该:

[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框架可能会带来固定的惩罚,即增加应用程序的总体内存占用(由于加载框架和实例化我不知道哪些对象);但是,您不应该在每次绘制纹理时都体验到意外的内存增加。

我认为您应该:

[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框架可能会带来固定的惩罚,即增加应用程序的总体内存占用(由于加载框架和实例化我不知道哪些对象);但是,您不应该在每次绘制纹理时都遇到意外的内存增加。

使用OpenGL释放内存的答案很简单:

与释放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帮助解决了我的问题

使用OpenGL释放内存的答案很简单:

与释放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帮助解决了我的问题

我用[图像发布]取代了免费版本,但问题依然存在。看起来和以前一模一样。有什么想法吗?此外,当我释放图像时,我仍然可以在屏幕上看到它(这是一个物体的纹理)。是否有任何openGL函数缓存图像?肯定有什么东西缓存了它,因为它仍然可见!非常感谢您的帮助!经过进一步调查,我发现512*512 PNG图像在磁盘上的大小为86 KB(在Finder中)。那么,为什么它在应用程序中占用超过3MB的内存呢?在删除对加载此图像的函数(上面粘贴的所有内容)的调用后,我在其上运行了Profiler/Instruments,它稳定在3.51 MB的“活动字节”,但如果调用该函数(肯定只调用了一次,我已经记录了它),则“活动字节”稳定在6.80 MB。请帮忙!!为什么会占用这么多内存?嗯。。。实际上,[图像发布]导致应用程序崩溃,错误程序收到信号:“EXC\u BAD\u ACCESS”。请查看我的编辑。我还找到了以下链接:。请尝试我的更改,看看它是否有助于减少内存消耗。我用[image release]替换了free,但问题仍然存在。看起来和以前一模一样。有什么想法吗?此外,当我释放图像时,我仍然可以在屏幕上看到它(这是一个物体的纹理)。是否有任何openGL函数缓存图像?肯定有什么东西缓存了它,因为它仍然可见!非常感谢您的帮助!经过进一步调查,我发现512*512 PNG图像在磁盘上的大小为86 KB(在Finder中)。那么,为什么它在应用程序中占用超过3MB的内存呢?在删除对加载此图像的函数(上面粘贴的所有内容)的调用后,我在其上运行了Profiler/Instruments,它稳定在3.51 MB的“活动字节”,但如果调用该函数(肯定只调用了一次,我已经记录了它),则“活动字节”稳定在6.80 MB。请帮忙!!为什么会占用这么多内存?嗯。。。实际上,[image release]会导致应用程序因程序接收到错误信号而崩溃: