代码之家  ›  专栏  ›  技术社区  ›  Nick Haddad

如何从qtkit获取图像数据而不进行颜色或gamma校正?

  •  8
  • Nick Haddad  · 技术社区  · 15 年前

    由于雪豹,qtkit现在正在从qtmovies frameimageattime:withattributes:error:等函数返回颜色校正的图像数据。给定一个未压缩的avi文件,相同的图像数据以更大的像素值显示在雪豹和雪豹之间。

    目前,我正在使用frameimageattime获取nsImage,然后请求该图像的tiffrepresentation。这样做之后,雪豹的像素值会略高一些。

    例如,Leopard中具有以下像素值的文件:

    [0 180 0]
    

    现在有一个像素值,比如:

    [0 192 0]
    

    有没有办法要求qtmovie提供未经颜色校正的视频帧?我应该要求CGIMAGEREF、CIIMAGE还是CVPIxelBufferRef?在读取视频文件之前,有没有一种方法可以完全禁用颜色校正?

    我试图通过使用nscalibratedcolrospace绘制nsbitmapImagerep来解决这个问题,但这只是我的一部分:

    // Create a movie
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys :
                          nsFileName, QTMovieFileNameAttribute,
                          [NSNumber numberWithBool:NO], QTMovieOpenAsyncOKAttribute,
                          [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
                          [NSNumber numberWithBool:NO], QTMovieLoopsBackAndForthAttribute,
                          (id)nil];
    _theMovie = [[QTMovie alloc] initWithAttributes:dict error:&error];
    
    
    // ....    
    
    NSMutableDictionary *imageAttributes = [NSMutableDictionary dictionary];
    [imageAttributes setObject:QTMovieFrameImageTypeNSImage forKey:QTMovieFrameImageType];
    [imageAttributes setObject:[NSArray arrayWithObject:@"NSBitmapImageRep"] forKey: QTMovieFrameImageRepresentationsType];
    [imageAttributes setObject:[NSNumber numberWithBool:YES] forKey:QTMovieFrameImageHighQuality];
    
    NSError* err = nil;
    NSImage* image = (NSImage*)[_theMovie frameImageAtTime:frameTime withAttributes:imageAttributes error:&err];
    
    
    // copy NSImage into an NSBitmapImageRep (Objective-C)
    NSBitmapImageRep* bitmap = [[image representations] objectAtIndex:0]; 
    
    // Draw into a colorspace we know about
    NSBitmapImageRep *bitmapWhoseFormatIKnow = [[NSBitmapImageRep alloc] 
                                                    initWithBitmapDataPlanes:NULL 
                                                    pixelsWide:getWidth() 
                                                    pixelsHigh:getHeight()
                                                    bitsPerSample:8 
                                                    samplesPerPixel:4 
                                                    hasAlpha:YES 
                                                    isPlanar:NO
                                                    colorSpaceName:NSCalibratedRGBColorSpace 
                                                    bitmapFormat:0
                                                    bytesPerRow:(getWidth() * 4)
                                                    bitsPerPixel:32];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmapWhoseFormatIKnow]];
    [bitmap draw];
    [NSGraphicsContext restoreGraphicsState];
    

    这确实会转换回“非颜色校正”的颜色空间,但颜色值与我们测试的未压缩avi文件中存储的值不完全相同。此外,由于它是从rgb->“设备rgb”->rgb转换而来,因此效率要低得多。

    另外,我在64位应用程序中工作,因此下拉到QuickTime-C API不是一个选项。

    谢谢你的帮助。

    1 回复  |  直到 13 年前
        1
  •  2
  •   Rab    13 年前

    这就是你遇到的问题: http://support.apple.com/kb/ht3712 此处还将参考qt进行说明: http://developer.apple.com/library/mac/#technotes/tn2227/_index.html

    应该有一个选择退出标志的colorsync(这是自动和无声的),但因为colorsync回到“碳扩散时代”,有很多困惑,如何禁用它从64位应用程序。它甚至可能存在,只是没有文档。但即使是Adobe也没有找到Afaik(64位Photoshop for OS X???)[编辑:事实上,也许他们用了CS5,或者找到了解决方法…因此,如果你有朋友在那里工作,他们可能是一种资源;)但是,我认为在64位OS X与Windows或32位操作系统上,他们的颜色可能会有所不同]。

    第一个链接说明如何强制gamma值为1.8系统范围和非编程方式。只是指出它-它可能只对您的应用程序有有限的用途,但很好知道。

    禁用colorsync的常用方法是/was

    GraphicsImportSetFlags( gi, kGraphicsImporterDontUseColorMatching ); 
    

    但我不知道这在64位应用程序中是否有效(很肯定不会)。事实上,很多与colorsync相关的事情更难做到64位,也许还不可能做到。只需搜索“site:apple.com colorsync 64位”。

    如果我找到更好的答案,我会编辑我的答案。可以说,我只是想这能帮助你了解敌人。

    另一个编辑:(重新)标记视频也可以缓解或消除这个问题,因为ColorSync以某种方式处理未标记的视频(请参阅链接),并根据标记对其进行不同的操作。视频的颜色特征是什么?试试sRGB吧?

    推荐文章