我已经跟随sample code on Apple's Quartz programming guide(清单2-5)和(在代码中纠正了几个拼写错误,例如calloc
,只有一个应该是malloc
的参数)I我的@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);
}
一切都很好,但是当我打电话给方法时什么都没有出现。
我的理解是,与drawInRect
不同,它需要UIView在图片中(没有双关语),这个位图绘制可以从任何类型的类中进行,即使你没有使用UIKit。
在这个例子中,我只是从viewDidLoad
调用方法作为测试,但我认为我可以从任何地方调用它,甚至是NSObject子类,并期望看到一些东西;至少,这是Apple的文档建议的。有什么想法吗?
更新:Apple文档中的进一步阅读使我尝试创建上下文,而不是使用之前定义的自定义函数:
// myBitmapContext = MyCreateBitmapContext (400, 300);// 3
UIGraphicsBeginImageContext(myBoundingBox.size);
myBitmapContext=UIGraphicsGetCurrentContext();
然而,结果仍然没有出现在屏幕上。另外,即使我没有直接调用malloc
:
malloc: *** error for object 0x102b1020: pointer being freed was not allocated*** set a breakpoint in malloc_error_break to debug
答案 0 :(得分:6)
你对在屏幕上绘制内容所需的内容感到困惑。您需要某种视图 - iOS应用中的UIView
或Cocoa应用中的NSView
。
这两种视图通常都要求您通过实现-drawRect:
方法来绘制它们。你不能(很容易)在其他时间吸引他们。 (这是一个巨大的过度概括,真的,但它足够接近。)
或者,将图像保存到文件中,然后打开文件。 (例如,将CGImageRef
包裹在UIImage
中,然后使用UIImagePNGRepresentation
创建PNG数据,然后-[NSData writeToFile:atomically:]
将其写入文件。)
您的代码也存在一些问题。 -testDrawCG
在此之前就可以了:
myImage = CGBitmapContextCreateImage (myBitmapContext);// 5
您已经获取了位图上下文的内容 - 您之前绘制的两个矩形 - 并从中创建了CGImageRef
。将此图像视为上下文的快照。
CGContextDrawImage(myBitmapContext, myBoundingBox, myImage);// 6
现在您将该图像绘制回相同的上下文。我不知道你为什么要这样做。跳过它。
char *bitmapData = CGBitmapContextGetData(myBitmapContext); // 7
现在,您将获得支持位图上下文的原始数据。你不需要这样做。
CGContextRelease (myBitmapContext);// 8
好的,你完成了上下文,有道理。
if (bitmapData) free(bitmapData); // 9
不要这样做!您没有使用名称中包含Create
或Copy
的方法获取数据,因此您不拥有它,也不应该将其释放。
CGImageRelease(myImage);
好的,很好,你完成了图像,所以你发布它。但是,由于你没有对图像做任何有用的事情,所以你不会看到它出现在任何地方也就不足为奇了。
答案 1 :(得分:0)
您需要将图像(myImage
)绘制到在屏幕上绘制的上下文中。创建UIView
的子类,并将testDrawCG
代码放入其drawRect:
方法中。然后,仍然在drawRect:
中,将myImage
绘制到视图的上下文中,如下所示:
CGContextDrawImage(UIGraphicsGetCurrentContext(), self.bounds, myImage);
答案 2 :(得分:0)
您可以随时绘制位图,但绘图会进入位图。如果你想看看你画了什么,你仍然需要在常规绘图周期中将它绘制到UIView或CALayer。
要完全控制您的绘图,请遵循rob mayoff的建议。如果您只想查看当前正在绘制的内容,可以将CGImageRef
变为UIImage
,并在UIImageView
内显示:
UIImage * image = [UIImage imageWithCGImage:myImage]; [someImageView setImage:image];
但是,这只是意味着使用我怀疑是否有任何Apple批准的方式在屏幕外绘制UIImageView
drawRect:
方法进行了绘图到屏幕。drawRect:
。