【问题标题】:What's wrong with my CGBitmapContext?我的 CGBitmapContext 有什么问题?
【发布时间】:2016-08-18 17:06:46
【问题描述】:

我无法在 python 中创建有效的 CGBitmapContext。它只是返回空值,然后导致其他所有内容都抱怨缺少定义和 python 崩溃。我尝试将内存分配设置为无,这意味着它应该自行排序,但这也不起作用。而且我认为也没有分配 objC 缓冲区。任何帮助将不胜感激。

#!/usr/bin/python

import os, sys, objc
from Quartz import *

os.environ["CG_CONTEXT_SHOW_BACKTRACE"] = '1'
resolution = 300 #dpi
scale = resolution/72

cs = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)
# Options might be: kCGImageAlphaNoneSkipLast, kCGImageAlphaPremultipliedLast \ or FIRST
transparency = kCGImageAlphaNoneSkipLast

#Save image to file
def writeImage (image, url, type, options):
    destination = CGImageDestinationCreateWithURL(url, type, 1, None)
    CGImageDestinationAddImage(destination, image, options)
    CGImageDestinationFinalize(destination)
    CFRelease(destination)
    return

if __name__ == '__main__':

    for filename in sys.argv[1:]:
        pdf = CGPDFDocumentCreateWithProvider(CGDataProviderCreateWithFilename(filename))
        numPages = CGPDFDocumentGetNumberOfPages(pdf)
        shortName = os.path.splitext(filename)[0]

        # For each page, create a file
        for i in range (1, numPages+1):
            page = CGPDFDocumentGetPage(pdf, i)
            if page:
        #Get mediabox
                mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox)
                x = CGRectGetWidth(mediaBox)
                y = CGRectGetHeight(mediaBox)
                x *= scale
                y *= scale
        # Allocate Memory, in this day and age.
                try:
                    rasterData = objc.allocateBuffer(int(4 * x * y))
                except  MemoryError: break
        # Create a Bitmap Context
                ctx = CGBitmapContextCreate(rasterData, x, y, 8, x, cs, transparency)
                CGContextSaveGState (ctx)
                CGContextScaleCTM(ctx, scale,scale)
                CGContextDrawPDFPage(ctx, page)
                CGContextRestoreGState(ctx)
        # Convert to an "Image"
                image = CGBitmapContextCreateImage(ctx) 
        # Create unique filename per page
                outFile = shortName + str(i) + ".tiff"
                url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, outFile, len(outFile), False)
        # kUTTypeJPEG, kUTTypeTIFF, kUTTypePNG
                type = 'kUTTypeTIFF'
                options = {
                    kCGImagePropertyTIFFXResolution : 300,
                    kCGImagePropertyTIFFYResolution : 300
                    }
                writeImage (image, url, type, options)
                CGContextRelease(ctx)
                del page

【问题讨论】:

  • bytesPerRowCGBitmapContextCreate 的参数看起来不对。如果您的位图为x 像素宽,并且它是每个组件8 位的RGBA 上下文,则每个像素占用4 个字节,因此bytesPerRow 应该是x * 4。 (请注意,当您分配内存时,您计算正确。)
  • 是的,我刚刚输入 0 来让 Mac 自行解决问题,而脚本现在似乎在其他地方失败了。所以,进步吧。

标签: python macos core-graphics


【解决方案1】:

输出提示我打开一些额外的日志记录:

os.environ["CG_CONTEXT_SHOW_BACKTRACE"] = '1'
os.environ["CGBITMAP_CONTEXT_LOG_ERRORS"] = '1'

然后这给了我以下信息,这似乎是 Apple 自己的文档中缺少的:

CGBitmapContextCreate: unsupported parameter combination:
    16 integer bits/component;
    48 bits/pixel;
    RGB color space model; kCGImageAlphaNone;
    14336 bytes/row.
Valid parameters for RGB color space model are:
    16  bits per pixel,      5  bits per component,      kCGImageAlphaNoneSkipFirst
    32  bits per pixel,      8  bits per component,      kCGImageAlphaNoneSkipFirst
    32  bits per pixel,      8  bits per component,      kCGImageAlphaNoneSkipLast
    32  bits per pixel,      8  bits per component,      kCGImageAlphaPremultipliedFirst
    32  bits per pixel,      8  bits per component,      kCGImageAlphaPremultipliedLast
    64  bits per pixel,      16 bits per component,      kCGImageAlphaPremultipliedLast
    64  bits per pixel,      16 bits per component,      kCGImageAlphaNoneSkipLast
    64  bits per pixel,      16 bits per component,      kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
    64  bits per pixel,      16 bits per component,      kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents
    128 bits per pixel,      32 bits per component,      kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
    128 bits per pixel,      32 bits per component,      kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents

因此,只需将透明度常量更改为 kCGImageAlphaPremultipliedLast 即可停止崩溃并修复上下文。但是,整个脚本仍然无法运行,我只收到了Trace/BPT trap: 5 作为回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2012-09-10
    • 2013-06-29
    • 2016-02-03
    • 2011-06-15
    • 2014-11-04
    • 2011-12-29
    相关资源
    最近更新 更多