Page 1 of 1

magick++: read mono8 image, save as PNG

Posted: 2015-11-17T08:55:12-07:00
by antenne
Hi all.

I have a bunch of GigE network cameras that provide raw grayscale pixel data (aka mono8). I intend to use magick++ to convert this to PNG for human consumption. I'm almost sure that this should be near trivial, but I can't get it to work properly. My code so far:

Code: Select all

void png::convert(void *dest, size_t *destsize,
                  void *src, size_t /*srcsize*/, size_t srcwidth, size_t srcheight) {
  Magick::Blob blob;

  Magick::Image im(srcwidth, srcheight, "R", Magick::CharPixel, src);
  im.type(Magick::GrayscaleType);
  im.depth(8);
  im.magick("png");
  im.write(&blob);

  memcpy(dest, blob.data(), blob.length());
  *destsize = blob.length();
}
The final output is not what I would expect. It appears that my gray data is read into a red channel, blue and green are untouched. Then, on GrayScale, a gray value is computed (probably) from all three channels. The final result is, unsurprising, not what I want. Hence, I spent most of the day trying to figure out how to either (a) tell the Image that there is only one channel or (b) how to duplicate the red channel into blue and green, such that I end up with the expected result. Alternatively, (c) find a completely different approach.

Any suggestions on how to proceed before I go bald? Thanks!

Re: magick++: read mono8 image, save as PNG

Posted: 2015-11-18T14:19:47-07:00
by glennrp
I believe the "R" means red channel. I'm not familiar with that programming interface but I guess "L" (Luma) might work.

Re: magick++: read mono8 image, save as PNG

Posted: 2015-11-18T14:26:19-07:00
by fmw42
I do not think IM recognizes "L" for luma. See http://www.imagemagick.org/script/comma ... hp#channel.

In IM 6 a grayscale image is 3 exactly the same channels for R,G,B and not a single channel image (as it will be in IM 7). So to create a grayscale image, you need to put the same image (channel) into each of the R,G,B channels.

I do not know this API, so cannot comment on the code.

Re: magick++: read mono8 image, save as PNG

Posted: 2015-11-20T06:49:14-07:00
by glennrp
fmw42 wrote:I do not think IM recognizes "L" for luma. See http://www.imagemagick.org/script/comma ... hp#channel.
Fred's right, "L" won't work. But that document does mention "Gray", so try that in place of "R" and let us know what happens.

Re: magick++: read mono8 image, save as PNG

Posted: 2015-11-25T03:29:11-07:00
by antenne
Thanks for your replies! Unfortunately, I can not use the commandline, but have to use the API directly. I didn't drill through the code to see how "gray" is implemented, but I suspect it's something along the lines I finally ended up doing. In case anyone is interested:

Code: Select all

void rgb(void **dest, size_t *destsize,
                 void *src, size_t srcsize, const std::string& srcformat) {

  std::string format;

  format.resize(srcformat.size());
  std::transform(srcformat.begin(), srcformat.end(), format.begin(), ::tolower);

  if (format == "mono8") {
    *destsize = 3 * srcsize;
    *dest = malloc(*destsize);

    for (char *destbyte = (char*)*dest, *srcbyte = (char*)src; srcbyte < (char*)src + srcsize; ++srcbyte) {
      *destbyte++ = *srcbyte;             // Red
      *destbyte++ = *srcbyte;             // Green
      *destbyte++ = *srcbyte;             // Blue
    }
...
Replace "R" in the first snippet by "RGB" and chain together. Don't forget to free() the rgb destination. Advantage: eventually I'll have to support other data formats that might come off a(nother) camera.