2012-04-08 11 views
1

私はであったはずの1つの引数でcallocのようなコードの2つのタイプミスを修正した後、sample code on Apple's Quartz programming guideをフォローしました。私@implementationビットマップコンテキストを使用して描画する方法

CGContextRef MyCreateBitmapContext (int pixelsWide, int pixelsHigh){ 

CGContextRef context = NULL; 
CGColorSpaceRef colorSpace; 
void *   bitmapData; 
int    bitmapByteCount; 
int    bitmapBytesPerRow; 

bitmapBytesPerRow = (pixelsWide * 4);// 1 
bitmapByteCount  = (bitmapBytesPerRow * pixelsHigh); 

colorSpace = CGColorSpaceCreateDeviceRGB(); 
bitmapData = malloc(bitmapByteCount);// 3 
if (bitmapData == NULL) 
{ 
    fprintf (stderr, "Memory not allocated!"); 
    return NULL; 
} 
context = CGBitmapContextCreate (bitmapData,// 4 
           pixelsWide, 
           pixelsHigh, 
           8,  // bits per component 
           bitmapBytesPerRow, 
           colorSpace, 
           kCGImageAlphaPremultipliedLast); 
if (context== NULL) 
{ 
    free (bitmapData);// 5 
    fprintf (stderr, "Context not created!"); 
    return NULL; 
} 
CGColorSpaceRelease(colorSpace);// 6 

return context;// 7 
} 

次のようにその後、私は方法があります:

-(void)testDrawCG{ 

CGRect myBoundingBox;// 1 

CGContextRef myBitmapContext; 
CGImageRef myImage; 



myBoundingBox = CGRectMake (100, 100, 100, 100);// 2 
myBitmapContext = MyCreateBitmapContext (400, 300);// 3 
// ********** Your drawing code here ********** // 4 
CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1); 
CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100)); 
CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5); 
CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200)); 
myImage = CGBitmapContextCreateImage (myBitmapContext);// 5 
CGContextDrawImage(myBitmapContext, myBoundingBox, myImage);// 6 
char *bitmapData = CGBitmapContextGetData(myBitmapContext); // 7 
CGContextRelease (myBitmapContext);// 8 
if (bitmapData) free(bitmapData); // 9 
CGImageRelease(myImage); 


} 

すべてが正常にコンパイルが、私はメソッドを呼び出すときに何も表示されません。

私の理解では、UIViewが画像内にあることが必要な(意図しない)のと違って、このビットマップ描画は、UIKitを使用していなくても、どのタイプのクラスからでも行うことができます。

この例では、メソッドをviewDidLoadから呼び出すだけですが、NSObjectサブクラスのどこからでも呼び出せると思います。少なくとも、それはアップルのドキュメントによって示唆されているものです。何かご意見は?

UPDATE:アップルのドキュメントでさらに読書は、コンテキストを作成するために、これを試すのではなく、以前に定義されたカスタム関数を使用するように私を導い:

// myBitmapContext = MyCreateBitmapContext (400, 300);// 3 
UIGraphicsBeginImageContext(myBoundingBox.size); 
myBitmapContext=UIGraphicsGetCurrentContext(); 

はしかし、結果はまだに表示されて何もありません画面。また、私は私が直接mallocを呼び出していない午前にもかかわらず、ログにこれを取得する:あなたが画面上に描画コンテキストに画像(myImage)を描画する必要が

malloc: *** error for object 0x102b1020: pointer being freed was not allocated*** set a breakpoint in malloc_error_break to debug 
+0

申し訳ありません。この質問はトピックから外れるかもしれませんが、どのようにしてobjective-cでこのサンプルコードを使用できましたか?メソッド形式はObjective-cにありません。私はquartzcoreを学び始めたばかりで、私の質問に答えることができれば感謝しています。ありがとう。 – cessmestreet

+0

@ user1681701 AppleのQuartzはC APIなので、Objective-Cが完全にサポートする「フォーマット」はCです。 – johnbakers

答えて

6

画面上に何かを描画するのに混乱します。 iOSアプリの場合はUIView、Cocoaアプリの場合はNSViewのような種類のビューが必要です。

両方の種類のビューでは、通常、-drawRect:メソッドを実装して描画する必要があります。他の時に(簡単に)描画することはできません。(これは本当に、広大なovergeneralizationですが、それは十分に近いです。)

また、ファイルに画像を保存し、ファイルを開きます。 (例えば、ファイルに書き込み、その後、PNGデータを作成するために-[NSData writeToFile:atomically:]UIImagePNGRepresentationを使用し、その後、UIImageCGImageRefを包む。)あなたのコードはまた、いくつかの問題があり

-testDrawCGはここまでOKです:あなたは、ビットマップコンテキストの内容撮影した

myImage = CGBitmapContextCreateImage (myBitmapContext);// 5 

- あなたは以前に描いた2つの長方形を - そしてそれらからCGImageRefを作成しました。このイメージをコンテキストのスナップショットと考えてください。

CGContextDrawImage(myBitmapContext, myBoundingBox, myImage);// 6 

は今、あなたは戻って同じコンテキストにその画像 を描いています。なぜあなたがこれをするのか分かりません。ちょうどそれをスキップします。

char *bitmapData = CGBitmapContextGetData(myBitmapContext); // 7 

これで、ビットマップコンテキストをバックアップする生データが得られました。これを行う必要はありません。

CGContextRelease (myBitmapContext);// 8 

いいえ、あなたは文脈で、意味があります。

if (bitmapData) free(bitmapData); // 9 

Do not do this!あなたは名前にCreateまたはCopyとメソッドを使用してデータを取得していない、したがって、あなたはそれを所有していないと、あなたはそれを解放しないでください。

CGImageRelease(myImage); 

[OK]をクリックします。これで画像は完成しました。しかし、イメージには何も役に立たなかったので、どこにも表示されないことは驚きではありません。

+0

私は、私が使用しているビューテクノロジに関係なく描画したいので、このアプローチを使用している理由はビットマップ描画にUIViewを必要としないことを読みました。 – johnbakers

+0

あなたは何を正確に読んでいますか?はい、UIViewを使用せずにビットマップに描画できます。これは、結果が自動的にかかわらず、画面に表示されますという意味ではありません - –

+0

おかげでクルト...あなたはまだそれを行うためにいくつかのコードを必要とし、通常の方法はいくつかの種類のUIViewのです。私がここに書いたコードは、Quartz 2Dプログラミングガイドと同じです。だから、Appleのサンプルコードのすべてがあまりにも厳密に従う価値があるわけではないと思います。 – johnbakers

0

UIViewのサブクラスを作成し、testDrawCGコードをdrawRect:メソッドに入れます。その後、まだdrawRect:で、このようなビューのコンテキストにmyImageを描く:

CGContextDrawImage(UIGraphicsGetCurrentContext(), self.bounds, myImage); 
0

はいつでもビットマップに描画することができますが、図面は、ビットマップになります。描画したものを見たい場合は、通常の描画サイクル中にUIViewまたはCALayerに描画する必要があります。

あなたの絵を完全にコントロールするには、rob mayoffさんの提案に従ってください。あなたはちょうどあなたが現在描画しているかを確認したい場合は、あなたのCGImageRefUIImageに向ける、および表示できるようUIImageView内:

UIImage *画像= [UIImage imageWithCGImage:MYIMAGE]; [someImageView setImage:image];

ただし、これは画面への描画がUIImageViewdrawRect:メソッドで発生したことを意味します。私はAppleが承認した方法で、drawRect:以外の画面に描画することはできません。

+0

技術的には、 'UIImageView'は' drawRect: 'をまったく使用しません。 [UIImageViewクラスリファレンス:特記事項](http://developer.apple.com/library/ios/documentation/uikit/reference/UIImageView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006889-CH3-DontLinkElementID_3 ) –

+0

@rob mayoff:ありがとう、私はそれに気付かなかった。 – Dondragmer

関連する問題