【问题标题】:Color accuracy problems rendering PDFs to image using Core Graphics on iOS在 iOS 上使用 Core Graphics 将 PDF 渲染为图像的颜色准确性问题
【发布时间】:2015-05-07 08:09:45
【问题描述】:

我在使用 iOS 上的 Core Graphics PDF 功能将某些 PDF 渲染为图像时遇到问题。具体来说,我使用的是这个库提供的UIImage+PDF 类别:https://github.com/mindbrix/UIImage-PDF。相关方法有:

来自“UIImage+PDF.m”

+(UIImage *)imageWithPDFData:(NSData *)data atSize:(CGSize)size atPage:(NSUInteger)page
{
    if(data == nil || CGSizeEqualToSize(size, CGSizeZero) || page == 0)
        return nil;

    UIImage *pdfImage = nil;

    CGFloat screenScale = [self screenScale];
    NSString *cacheFilename = [ self cacheFilenameForData:data atSize:size atScaleFactor:[self screenScale] atPage:page ];

    if(_shouldCacheOnDisk && [[ NSFileManager defaultManager ] fileExistsAtPath:cacheFilename ])
    {
        pdfImage = [ UIImage imageWithCGImage:[[ UIImage imageWithContentsOfFile:cacheFilename ] CGImage ] scale:[self screenScale] orientation:UIImageOrientationUp ];
    }
    else
    {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef ctx = CGBitmapContextCreate(NULL, size.width * screenScale, size.height * screenScale, 8, 0, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
        CGContextScaleCTM(ctx, screenScale, screenScale);

        [PDFView renderIntoContext:ctx url:nil data:data size:size page:page];
        CGImageRef image = CGBitmapContextCreateImage(ctx);
        pdfImage = [[UIImage alloc] initWithCGImage:image scale:screenScale orientation:UIImageOrientationUp];

        CGImageRelease(image);
        CGContextRelease(ctx);
        CGColorSpaceRelease(colorSpace);

        if(_shouldCacheOnDisk && cacheFilename)
        {
            [ UIImagePNGRepresentation( pdfImage ) writeToFile:cacheFilename atomically:NO ];
        }
    }

    return pdfImage;
}

并来自“PDFView.m”

+(void)renderIntoContext:(CGContextRef)ctx url:(NSURL *)resourceURL data:(NSData *)resourceData size:(CGSize)size page:(NSUInteger)page
{
    if ( resourceURL || resourceData )
    {
        /*
         * Reference: http://www.cocoanetics.com/2010/06/rendering-pdf-is-easier-than-you-thought/
         */
        CGPDFDocumentRef pdf;

        if( resourceURL )
        {
            pdf = CGPDFDocumentCreateWithURL( (__bridge CFURLRef) resourceURL );
        }
        else
        {
            CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)resourceData);
            pdf = CGPDFDocumentCreateWithProvider(provider);
            CGDataProviderRelease(provider);
        }

        CGPDFPageRef page1 = CGPDFDocumentGetPage( pdf, page );

        CGRect mediaRect = CGPDFPageGetBoxRect( page1, kCGPDFCropBox );
        CGContextScaleCTM( ctx, size.width / mediaRect.size.width, size.height / mediaRect.size.height );
        CGContextTranslateCTM( ctx, -mediaRect.origin.x, -mediaRect.origin.y );

        CGContextDrawPDFPage( ctx, page1 );
        CGPDFDocumentRelease( pdf );

    }
}

我得到的结果好坏参半。许多 PDF 似乎可以正确呈现。但是,有些存在一些严重的色彩准确性问题。下面是原文的一个例子:

还有糟糕的渲染:

如您所见,问题主要在于 RGB 中的绿色通道(CMYK 中的青色?)。所以我的假设是,这是一个色彩空间/色彩配置文件问题,呈现不佳的 PDF。一些搜索使我遇到了类似的问题:pdf images color space trouble ios。作者指出,他将问题归咎于 PDF 中缺少颜色配置文件,他的解决方案是要求他的设计师嵌入颜色配置文件。我不知道如何验证这是否是我的问题,并且该解决方案对我来说可能不可行,因为我无权访问原始文件或原始设计者。

如果有人可以就我如何在代码中处理这些 PDF 以纠正颜色问题(例如添加颜色配置文件、使用不同的颜色空间等)或我可以如何预- 在 iOS 设备上渲染之前在计算机上处​​理 PDF,我将不胜感激!

【问题讨论】:

  • 我们确实需要查看示例 PDF 文件以确定问题所在。在我看来,它“最有可能”是由 CMYK->RGB 转换引起的,并且不太可能通过添加 OutputIntent 颜色配置文件来解决。尽管将颜色空间转换为 ICCBased 可能会起作用。不知道文件中的内容很难说。
  • 感谢@KenS 的反馈。如果它有帮助,我在这里放了一个示例 PDF:dl.dropboxusercontent.com/u/18408411/sample.pdf
  • 快速看了一下,“看起来”颜色都是用 CMYK 指定的,包括具有 CMYK 色调变换的 Separatio9n 颜色。转换 CMYK->RGB 的指定方法(在 PDF 参考中)非常粗糙,我相信这就是导致您的问题的原因。你没有说你要渲染成什么图像格式,如果你可以渲染成 CMYK 图像,那应该没问题。否则,如果您需要渲染为 RGB,您要么必须获得具有 RGB 颜色的 PDF,要么使用更好的东西来进行渲染。你考虑过 Ghostscript 还是 MuPDF(还有其他解决方案)
  • 非常感谢@KenS。我使用的 UIImage+PDF 库使用 RGB 颜色空间呈现为 CGBitmapContext(内存位图格式)。如果我错了,请纠正我,但我的印象是,这是在 iOS 上使用 CoreGraphics 呈现 PDF 的唯一可行选项。我还没有查看其他库来进行渲染,因为这似乎会使过程变得非常复杂,但就像你一样,它可能是我唯一的选择之一。
  • 我不想这么说,但我对 iOS 一无所知 :-( 如果它接受除 RGB 以外的任何东西,我会感到惊讶 :-) 如果您要接受任意格式的 PDF 文件,并且颜色保真度对您很重要,那么我认为您将不得不使用不同的库。

标签: ios objective-c pdf colors core-graphics


【解决方案1】:

我从 Adob​​e Illustrator 导出的 PDF 也遇到了同样的问题。

我可以通过在导出期间更改 Illustrator 包含的颜色配置文件来解决此问题。

默认情况下,它使用“工作 CMYK”,将其更改为“通用 RGB 配置文件”即可解决问题。

如果您有 Illustrator 的副本,您应该能够打开现有的 PDF 文件,并使用正确的个人资料信息“另存为...”。

之前:
之后:

用于正确渲染的设置:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    相关资源
    最近更新 更多