Конвертировать PDF в CGImage превращает изображение в негатив

У меня есть следующий фрагмент кода для преобразования страницы PDF в CGImage:

func testPrint(pp:UnsafePointer<Void>) { // debug to see bits
  var p = UnsafePointer<UInt8>(pp)
  var res = ""
  for _ in 0..<200 {
    res += "\(p.memory) "
    p = p.advancedBy(1)
  }
  print(res)
}

func pageOneFromPDF(file:String) -> CGImage? {
  let url =  NSURL(fileURLWithPath: file)
  let pdfDocument = CGPDFDocumentCreateWithURL(url)
  let pageOne = CGPDFDocumentGetPage(pdfDocument, 1)
  let rect = CGPDFPageGetBoxRect(pageOne, .MediaBox)

  let width = Int(rect.size.width)
  let height = Int(rect.size.height)
  let context = CGBitmapContextCreate(nil, width, height, 8, width, CGColorSpaceCreateDeviceGray(), CGImageAlphaInfo.Only.rawValue)!
  CGContextClearRect(context, rect)
  CGContextDrawPDFPage(context, pageOne)
  testPrint(CGBitmapContextGetData(context))
  return CGBitmapContextCreateImage(context)
}

Это действительно преобразует мою страницу PDF в растровую карту с серой шкалой. Единственная проблема: в результате цвет CGImage инвертирован (черный становится белым и наоборот). Я возился с параметрами CGBitmapContextCreate, но безуспешно.

P.S. Я добавил этот фрагмент кода, чтобы обратить негативное на позитивное:

func inverse(pp:UnsafePointer<Void>, size:Int) {
  var p = UnsafeMutablePointer<UInt8>(pp)
  for _ in 0..<size {
    p.memory = 255-p.memory
    p = p.advancedBy(1)
  }
}

что работает, но, конечно, я хотел бы в первую очередь получить правильное изображение.

РЕДАКТИРОВАТЬ: Думаю, я, должно быть, делаю что-то глупое. Когда я визуализирую, как указано выше, и инвертирую все изображение, это выглядит как

введите описание изображения здесь

где слева это предварительный просмотр Finder, а справа мой рендеринг. Как я теперь заметил, это инвертирует части изображения. Я пробовал использовать код @Tricertops и получил (черные блоки выше / ниже из списка с другими PDF-файлами)

введите описание изображения здесь

и, очевидно, у него правильные значения серого, но есть некоторая черная маска, которая скрывает изображение. Чистый текст слева теперь невидим, но изображения отображаются правильно.


person qwerty_so    schedule 01.07.2016    source источник


Ответы (2)


Передавая CGImageAlphaInfo.Only, вы запрашиваете альфа-маску, а не изображение в градациях серого, как вы думаете.

Сначала попробуйте инициализировать контекст с помощью CGImageAlphaInfo.None (потому что у PDF-файлов нет альфа-канала):

CGBitmapContextCreate(nil, width, height, 8, width, CGColorSpaceCreateDeviceGray(), CGImageAlphaInfo.None.rawValue)

Затем залейте контекст белым цветом, как всегда в PDF-файлах:

CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
CGContextFillRect(context, rect)

Затем продолжите, как и раньше, нарисовав страницу PDF.


Я думаю, вы получали альфа-растровое изображение, а не оттенки серого. Нули, где ничего не было нарисовано (и PDF определяет этот белый цвет), и те, где было нарисовано какое-то содержимое (возможно, оно было черным). Это могло появиться при проверке битов как инвертированного серого растрового изображения. Всегда отлаживайте изображения как визуализированные, а не распечатанные по битам :)

person Tricertops    schedule 15.07.2016
comment
Я пробовал это, но все еще не понял сути. Я добавил дополнительную информацию к своему вопросу. - person qwerty_so; 15.07.2016
comment
Не знаю, что я сделал вчера, но, очевидно, я был недостаточно в сознании. На самом деле это то, чего мне не хватало. Большое спасибо! - person qwerty_so; 16.07.2016

Попробуйте создать контекст изображения без альфа-канала:

let context = CGBitmapContextCreate(nil, width, height, 8, width, CGColorSpaceCreateDeviceGray(), kCGImageAlphaNoneSkipLast)
person Lookaji    schedule 01.07.2016
comment
Это будет CGImageAlphaInfo.NoneSkipLast.rawValue, что недопустимо в документации и приводит к исключению. И kCGImageAlphaNone возвращает весь черный цвет ... - person qwerty_so; 01.07.2016
comment
извините, я не смог это проверить. Для справки я имел в виду эту SO ссылку и это. - person Lookaji; 02.07.2016
comment
Оба они относятся к цвету. Мне нужны оттенки серого. Что касается второй ссылки на документы, которые вы видите, это не сработает. - person qwerty_so; 02.07.2016
comment
Я пробовал использовать как RGB pdf, так и CMYK, и получил только растровый (черно-белый) рендеринг. без оттенков серого. - person Lookaji; 03.07.2016