2011-07-14 8 views
1

私の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によって解放されていないようです。何か不足していますか?これらの機能の1つによってキャッシュされていますか?さらに、画像を後で読み込むと、画像が2回ロードされたように見えます。つまり、アルファチャンネルは最初の2倍です。また、私がメモリを解放して3回目にリロードすると、アルファチャンネルは最初の3倍になります。ほぼ透明であるはずの部品はますます不透明になっています。

透明性に関する問題は、iOS 3、iOS 4では認識されませんでした。しかし、メモリが解放されないという問題は、両方で気付きました。

私にこれを手伝ってもらえますか?私はあまりにも多くの時間を画像で混乱させて過ごしました!また、私は愚かな画像を使用しているとは思わない:約40画像を使用するゲームを作っている。その大部分は128x128 PNGである。どのように私はすぐにメモリが不足している?このシナリオの「一般的な」プラクティスは何ですか?画像が必要ないときに私は記憶を解放しようとしていますか?

返信いただければ幸いです!ありがとうございました。

答えて

0

私は、あなたがすべきだと思う:

[image release]; 

代わり

CGImageRelease(imageRef); 

で実際にあなたが配分されているオブジェクトが、あなたはそのメンバーの1への参照を取得し、imageです。メンバーへの参照ではなく、割り当てた元のオブジェクトへの参照を解放する必要があります。 *image*imageRefのすべての使用状況が私には正しいようではありません

;:あなたはfree(*image);

EDITを呼び出す必要はありません。メモリ消費量について

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); 

:あなたの代わりにimageimageRefを使用する必要があり、私はOpenGLESのフレームワークを使用すると、すなわち、固定ペナルティを強要によるフレームワークをロードし、Iをインスタンス化する(あなたのアプリケーションの全体的なメモリフットプリントを増やすかもしれないと思いますどのオブジェクトがわからない)。テクスチャを描画するたびに予期しないメモリ増加が発生することはありません。

+0

無料で[画像のリリース]に置き換えましたが、問題は残ります。以前とまったく同じように見えます。何か案は? – Sam

+0

さらに、私が画像を放つと、私は画面上でそれを見ることができます(それはオブジェクトのテクスチャです)。 OpenGL関数のいずれかが画像をキャッシュしていますか?確かに何かがキャッシュされている、それはまだ目に見えるので!ヘルプは非常に感謝! – Sam

+0

さらに調査したところ、私は、512 * 512のPNGイメージが(Finderの)ディスク上にサイズ86 KBを持つことを発見しました。だからなぜそれは3 MB以上のメモリをアプリで使用するのだろうか?私はこのイメージをロードする関数(上に貼り付けたすべて)の呼び出しを取り除いた後、Profiler/Instrumentsを実行しました。3.51 MBの "Live Bytes"で安定していましたが、関数が呼び出されるとNSLoggedしている)、 "ライブバイト"は6.80 MBで安定します。助けてください!!それはなぜそんなにメモリを使い果たしているのですか? – Sam

1

OpenGLを使用するときにメモリを解放への答えは簡単です:UIImageによって使用されるメモリを解放http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml

は、OpenGLが使用するテクスチャを自由に比べてほとんど目立たないです。問題は、次のコードである:

GLuint textures[100]; // allows total of 100 textures 

location = textures[imageNo]; 

glBindTexture(GL_TEXTURE_2D, location); 

そして、それをすることによって解決される:それは私が回り込むいますので、私は本当に、これはiPhone上でのOpenGLのテクスチャを使用して、他の誰かの役に立つとなり願ってい

void unloadImage(GLuint imageNo) 
{ 
    [textureImages[imageNo] release]; 
    glDeleteTextures(1, &textures[imageNo]); 
} 

年齢のサークルで!

そして、私の問題に協力した@sergioに感謝します!

+0

、ありがとう! +1 – sergio

+0

これはまた、CGContextDrawImageの直後にUIImageを解放できることを意味します(つまり、実際に画像が完成するまで待つ必要はありません)。これはいくつかには明らかかもしれませんが、UIImageを公開してメモリが解放されなかった理由を理解しようとしました。 – Sam

関連する問題