Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.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
Ios 在位图上下文中逐行绘制的有效方法_Ios_Xcode_Performance_Bitmap_Core Graphics - Fatal编程技术网

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更新)。但是,在这种情况下,您可能也不希望异步调度它(因为最终可能会导致主队列备份的请求比它处理请求的速度更快)

我建议将图像重画与处理下载数据的循环分离。有两种机制可以实现这一点,这两种机制都需要确保后台进程不会向主队列本身分派任何内容,而是:

  • 在后台线程中更新像素缓冲区,但在将更新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处理程序
    ,监听这些合并事件

  • 这两种技术都允许您在后台线程中进行处理,以尽可能高的频率使用UI进行更新,但既不会降低后台任务到UI更新速度的风险,也不会使用UI更新请求延迟主线程


    显然,要确保从两个线程访问的对象都正确同步。您需要确保主线程使用的数据不会同时被后台线程改变。

    顺便说一句,大多数图像格式都经过了相当大的压缩,而不是发送原始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) ;
    
    }