Magick++ C++ Ввод 16-битные оттенки серого PNG

У меня есть серия файлов PNG, которые, как я знаю, имеют 16-битный формат оттенков серого. У меня не было проблем с загрузкой этого с помощью Magick++ и получением доступа к данным в 8-битном формате (это было сделано в первую очередь потому, что весь код был там и никаких изменений не требовалось).

magick_image->write(0, 0, grey->GetWidth(), grey->GetHeight(), "R", Magick::CharPixel, grey->GetBeginData());

Обратите внимание, что серый находится в нашем собственном контейнере для изображений, но разметка памяти — это всего лишь один блок заранее выделенной памяти.

Мне сказали, что нам нужно получить доступ ко всему 16-битному диапазону, и я не очень понимаю, как это сделать. Я предполагаю, что не стал бы использовать Magick::CharPixel, но другие, описанные в документации, не указывают, какой размер бит они имеют на самом деле.


Итак, мне нужно уметь делать следующие вещи:

  • Определите, является ли это 16-битным изображением в первую очередь
  • Чтение из класса Magick::Image в блок памяти, который будет отображаться для размещения в блоке памяти для u_int16_t

Может кто-нибудь помочь с этим?


person AdmiralJonB    schedule 06.05.2015    source источник
comment
Из цветных документов квантовая глубина 16 будет Magick::ShortPixel   -  person emcconville    schedule 06.05.2015
comment
Большой! Я искал что-то подобное, но просто не нашел. Я испытаю это, как только у меня будет возможность. Теперь мне просто нужно найти способ определить квантовую глубину загруженного изображения.   -  person AdmiralJonB    schedule 07.05.2015
comment
Лучше перепроверьте документы, но Magick::Image.depth должно дать вам 8, 16 или 32.   -  person emcconville    schedule 07.05.2015
comment
Из того, что я вижу в документах, похоже, что это позволяет вам только указать глубину, а не определить, что это такое...   -  person AdmiralJonB    schedule 07.05.2015


Ответы (1)


Есть несколько способов сделать это, но, не видя определений magick_image и grey, этот ответ основан на нескольких предположениях.

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

struct MaybeGray {
    std::vector<u_int16_t> blob;
    size_t width;
    size_t height;
    MaybeGray(size_t w, size_t h) : blob(w * h) { width = w; height = h; };
    size_t getWidth() { return width; };
    size_t getHeight() { return height; };
    void * getBeginData() { return blob.data(); } // C11? Is this allowed?
};

Затем я создам изображение холста 2x2, чтобы удовлетворить magick_image.

Magick::Image magick_image;
Magick::Geometry size(2, 2);
magick_image.size(size);
magick_image.read("XC:blue");
// Apply gray scale (Magick::Image.quantize may be better.)
magick_image.type(Magick::GrayscaleType);

Определите, является ли это 16-битным изображением в первую очередь

Magick::Image.depth можно использовать для идентификации и установки значения глубины.

const size_t DEPTH = 16;
if ( magick_image.depth() != DEPTH ) {
    magick_image.depth(DEPTH);
}

Чтение из класса Magick::Image в блок памяти, который будет отображаться для размещения в блоке памяти для u_int16_t

То, что вы делаете с Magick::Image.write, правильно. Однако Magick::CharPixel будет для 8-битной, 256 цветов, глубины. Для 16-битного используйте Magick::ShortPixel.

struct MaybeGray gray(2, 2);
magick_image.write(0, 0,
                   gray.getWidth(),
                   gray.getHeight(),
                   "R",
                   Magick::ShortPixel,
                   gray.getBeginData());

Как проверить

Холст изображения XC:red должен заполнять блоб 0xFFFF, а XC:black0x0000. Используйте утилиты ImageMagick convert и identify для получения ожидаемых результатов.

# Create identical canvas
convert -size 2x2 xc:blue -colorspace gray -depth 16 blue.tiff
# Dump info
identify -verbose blue.tiff

  Image: blue.tiff
  Format: TIFF (Tagged Image File Format)
  Class: DirectClass
  Geometry: 2x2+0+0
  Units: PixelsPerInch
  Type: Grayscale
  Base type: Grayscale
  Endianess: LSB
  Colorspace: Gray
  Depth: 16/14-bit
  Channel depth:
    gray: 14-bit
  Channel statistics:
    Gray:
      min: 4732 (0.0722057)
      max: 4732 (0.0722057)
      mean: 4732 (0.0722057)
      standard deviation: 0 (0)
      kurtosis: 0
      skewness: 0
  Colors: 1
  Histogram:
         4: ( 4732, 4732, 4732) #127C127C127C gray(7.22057%)
  # ... rest omitted

И подробная информация подтверждает, что у меня 16-битное серое изображение, а гистограмма сообщает мне, что MaybeGrey.blob будет заполнено 4 0x127C.

16-битный PNG в оттенках серого

Что это такое.

person emcconville    schedule 07.05.2015
comment
Извините за долгое ожидание. Теперь это действительно работает, по какой-то причине автозаполнение, которое я использую, не думало, что оно имеет возвращаемое значение... Спасибо! - person AdmiralJonB; 21.05.2015