Ios 在位图上下文中逐行绘制的有效方法
我有一个应用程序,它从网络中一行一行地绘制图像数据。我想展示这个更新过程,而不仅仅是最终的图像 我绘制此图的原始代码如下所示:Ios 在位图上下文中逐行绘制的有效方法,ios,xcode,performance,bitmap,core-graphics,Ios,Xcode,Performance,Bitmap,Core Graphics,我有一个应用程序,它从网络中一行一行地绘制图像数据。我想展示这个更新过程,而不仅仅是最终的图像 我绘制此图的原始代码如下所示: dispatch_sync(dispatch_get_main_queue(),^(void){ for (int i=0;i<len; i = i+3) { float r = 1.0*byteData[i]/256; float g = 1.0*byteData[i+1]/256
dispatch_sync(dispatch_get_main_queue(),^(void){
for (int i=0;i<len; i = i+3)
{
float r = 1.0*byteData[i]/256;
float g = 1.0*byteData[i+1]/256;
float b = 1.0*byteData[i+2]/256;
CGContextSetRGBFillColor(myView->bitmapContext, r,g,b, 1.0f) ;
CGContextFillRect (g_myView->bitmapContext, CGRectMake(y, x, 1.0f, 1.0f)) ;
x++;
}
});
现在,您正在同步地将UI的更新发送回主循环。这意味着(大概)图像数据的背景处理将不得不等待 通常,我建议异步调度(以避免后台进程等待UI更新)。但是,在这种情况下,您可能也不希望异步调度它(因为最终可能会导致主队列备份的请求比它处理请求的速度更快) 我建议将图像重画与处理下载数据的循环分离。有两种机制可以实现这一点,这两种机制都需要确保后台进程不会向主队列本身分派任何内容,而是:
CADisplayLink
。显示链接类似于NSTimer
,只是它链接到UI的更新dispatch\u source\u type\u DATA\u ADD
的dispatch source跟踪接收到的像素数。同样,在后台线程中更新像素缓冲区,让它执行dispatch\u source\u merge\u data
以更新此像素计数。然后在主线程上有一个dispatch\u source\u set\u event\u处理程序
,监听这些合并事件显然,要确保从两个线程访问的对象都正确同步。您需要确保主线程使用的数据不会同时被后台线程改变。顺便说一句,大多数图像格式都经过了相当大的压缩,而不是发送原始RGB字节数据。如果发送原始RGB数据,请注意传输速度将比标准图像下载慢得多。因此,您可能会牺牲整体性能,以便在下载时观看下载。如果你必须这样做,就这样做吧,但要注意抵消的考虑。
CGContextRef context = [myView createCustomBitmapContextWithSize: CGSizeMake(1024.0f, 1.0f)] ;
for (int i=0;i<len; i = i+3)
{
float r = 1.0*byteData[i]/256;
float g = 1.0*byteData[i+1]/256;
float b = 1.0*byteData[i+2]/256;
CGContextSetRGBFillColor(context, r,g,b, 1.0f) ;
CGContextFillRect (context, CGRectMake(y, 0, 1.0f, 1.0f)) ;
x++;
}
dispatch_sync(dispatch_get_main_queue(),^(void){
CGImageRef image = CGBitmapContextCreateImage(context);
CGContextDrawImage(myView->bitmapContext, CGRectMake(0,x,1024.0f,1.0f), image);
});
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext() ;
CGImageRef myImage = CGBitmapContextCreateImage(bitmapContext) ;
CGContextDrawImage(context, rect, myImage) ;
CGImageRelease(myImage) ;
}