equivalent of random noise in Magick++

1k views Asked by At

I've found a lot of documentation online about using ImageMagick's command line functions to create images of random noise, but have not been able to figure out how to reproduce that in Magick++.

ImageMagick has the +noise method Random:

convert -size 100x100 xc: +noise Random random.png

I would like to be able to set a pixel to Color("random"), for example:

sought.extent(Geometry(640,416), Color("random"), CenterGravity);

To embed a smaller image in a canvas of random noise. Of course, random isn't an acceptable argument for Color, but I'm wondering if the equivalent exists? The ideal would be if it were also possible to limit the range of colors - for example only 12-bit (#000-#FFF).

1

There are 1 answers

5
emcconville On BEST ANSWER

The method Magick::Image::addNoise() is a good place to start, but if you really want random/random. Use -fx "rand()".

#include <Magick++.h>

int main(int argc, const char ** argv) {

    Magick::InitializeMagick(*argv);
    Magick::Image image("100x100", "gray50");

    image.fx("rand()");
    image.write("noise.jpg");

    return 0;
}

noise

Edited by Mark Setchell

Much as I dislike editing other people's posts, I wanted to add something that is too big for a comment and not a competing answer, so this is the only way I know. Please feel free to ignore/delete/dissociate from this part!

If OP wants numbers corresponding to 12-bit values, I did a little experiment at the commandline like this to see how I could force that:

convert -size 10000x1 xc:gray -fx "(rand*4096)/quantumrange" -depth 16 -compress none pgm:- | sed '1,3d' | tr " " "\n" | sort -n

That generates a 1000 pixel image and forces the output to be an uncompressed PGM file that you can see the values in. I then sort them to see what the biggest value generated is, and it is 4096. So, I think the -fx expression I am suggesting ((rand*4096)/quantumrange) may help generate 12-bit values.

Additional Update

For mapping a region with random colors, an FX expression may look something like...

(i<100 & j<480) ? rand() : u

The i & j or x/y offsets, and the u is a the original image. A fun options, but traversing all the pixels will be slow. A faster option would be to create a random color image instance and use Magick::Image.composite to place the image on top of another.

#include <Magick++.h>

using namespace Magick;

int main(int argc, const char ** argv) {
  InitializeMagick(*argv);

  Image wizard("wizard:");
  Image rand_img("100x100", "gray50");
  rand_img.fx("rand()");

  wizard.composite(rand_img, 225, 225);

  wizard.write("wizards_make_magick.png");

  return 0;

}

Wizards do make magick