2016-08-18 2 views
0

У меня возникли проблемы с созданием допустимого CGBitmapContext в python. Он просто возвращает нулевые значения, что затем заставляет все остальное жаловаться на отсутствие ошибок определения и python. Я пробовал установить распределение памяти на None, а это значит, что он должен разбираться, но это тоже не работает. И я не думаю, что буфер objC также выделяется. Любая помощь будет принята с благодарностью.Что случилось с моим CGBitmapContext?

#!/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 
+1

Аргумент 'bytesPerRow' для' CGBitmapContextCreate' выглядит неправильно. Если ваш битмап имеет ширину 'x', и это контекст RGBA с 8 бит на компонент, каждый пиксель занимает 4 байта, и поэтому bytesPerRow должен быть« x * 4 ». (Обратите внимание, что когда вы выделили память, вы правильно выполнили математику.) –

+0

Да, я только что положил 0, чтобы заставить Mac работать для себя сам, и скрипт, кажется, сейчас не работает в другом месте. Итак, прогресс. – benwiggy

ответ

0

Выход предложил мне включить некоторые дополнительные протоколирования:

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 в качестве ответа.