using readable pixeldata from an Image

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
ramy_d

using readable pixeldata from an Image

Post by ramy_d »

hi,

so I am trying to use the Magick++ library to do some image manipulation to an image.
I can get a pixel array from the image, so my question is, how do can i use a pixel array to push it into a readPixels() function and how can i get it to fit my pixel array format when i do a getPixels() - i don't like this pixelpacket business >.<

ok, here's some pseudo code:

Code: Select all

    #include <ImageMagick/Magick++.h>
    using namespace Magick;

    Image blank_image("320x240", "white");
    PixelPacket *mypixelpacket;

    myMovie.loadMovie("movies/myMovie.mov");
    myMovie.play();
    myMovie.setLoopState(OF_LOOP_NORMAL);

    while (1) {
        myMovie.update(); //update the video frame
        bool bNewFrame = false;
        bNewFrame = myMovie.isFrameNew(); //checks if the video is at a new frame since the app runs more than 30 fps
        if (bNewFrame) { //if we are at a new frame
            blank_image.readPixels(RGBQuantum, myMovie.getPixels() ); //tell the blank_image to read the pixels from myMovie
            blank_image.blur(6, 1.5); //blur the image
            blank_image.syncPixels(); //sync pixels
            mypixelpacket = blank_image.getPixels(0,0,320,240); //put the pixels in a pixel packet
            myMagickImage.setFromPixels((unsigned char*)mypixelpacket, 320, 240, RGBImage); //convert the pixel packet to an unsigned char array and feed it
        }

        myMovie.draw(20,20); //draws the video at X:20 and Y:20 on a canvas
        myMagickImage.draw(400, 20); //draws the image at it's respective X and Y next to it.
    }
myMovie.getPixels() returns a pixel array that would like this

Code: Select all

myMovie.getPixels() == unsigned char myPixelArray[widthOfImage*HeightOfImage*AmmountOfDataPerPixel] = { 10, 30, 100, 63, 42, 86, 24}
these values are ordered RGB or RGBA (in our example, it's RGB, hence RGBQuantum ) so 10 is Red, 30 is Green, 100 is Blue 63 is Red, 42 is Green, 86 is Blue etc.

now with this setup i get a bunch of lines in my Magick image, see my image link, original is on the left, modified is on the right.
Image

and in a very weird twist, although i can do this:

Code: Select all

myMagickImage.setFromPixels((unsigned char*)mypixelpacket, 320, 240, RGBImage); 
i can't do this:

Code: Select all

unsigned char *myPixelArray = (unsigned char*)mypixelpacket;
which is the most frustrating part, because if i could, i could evaluate the data, print it out, i could solve this, but i can't because the pixel packet structure is very weird to me.

sooo, any help on this pixelpacket to to unsigned char issue i am having?
ramy_d

Re: using readable pixeldata from an Image

Post by ramy_d »

oooo snap

ok so now i have this going on:
Image

why are there 4 of them!

here's some pseudo code:

Code: Select all

    #include <ImageMagick/Magick++.h>
    using namespace Magick;

    Image blank_image("320x240", "white");
    PixelPacket *mypixelpacket;

    myMovie.loadMovie("movies/myMovie.mov");
    myMovie.play();
    myMovie.setLoopState(OF_LOOP_NORMAL);

    unsigned char myPixels[320*240*3];

    while (1) {
        myMovie.update(); //update the video frame
        bool bNewFrame = false;
        bNewFrame = myMovie.isFrameNew(); //checks if the video is at a new frame since the app runs more than 30 fps
        if (bNewFrame) { //if we are at a new frame
            blank_image.readPixels(RGBQuantum, myMovie.getPixels() ); //tell the blank_image to read the pixels from myMovie
            blank_image.blur(6, 1.5); //blur the image
            blank_image.syncPixels(); //sync pixels
            mypixelpacket = blank_image.getPixels(0,0,320,240); //put the pixels in a pixel packet

            for (int i=0; i < 320*240; i++) { map the pixelpacket struct to a char array
                myPixels[((i+1)*3)-3] = (int) sqrt( mypixelpacket[i].red );
                myPixels[((i+1)*3)-2] = (int) sqrt( mypixelpacket[i].green );
                myPixels[((i+1)*3)-1] = (int) sqrt( mypixelpacket[i].blue );
            }

            myMagickImage.setFromPixels(myPixels, 320, 240, RGBImage); //feed the character array
        }

        myMovie.draw(20,20); //draws the video at X:20 and Y:20 on a canvas
        myMagickImage.draw(400, 20); //draws the image at it's respective X and Y next to it.
    }

soooooooo

why is this happening?
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: using readable pixeldata from an Image

Post by magick »

Type
  • convert -version
Is your version Q16? If so there are 2 bytes per pixel component. You can add -quantum-depth=8 to your configure script command line and rebuild and reinstall ImageMagick. That produces a Q8 version of ImageMagick where each pixel component is 8-bits (0..255).
ramy_d

Re: using readable pixeldata from an Image

Post by ramy_d »

magick wrote:Type
  • convert -version
Is your version Q16? If so there are 2 bytes per pixel component. You can add -quantum-depth=8 to your configure script command line and rebuild and reinstall ImageMagick. That produces a Q8 version of ImageMagick where each pixel component is 8-bits (0..255).
oh shoot, it is Q16!
so my problem is here, when i get the pixel array from my image into the imageMagick's image, there is some kind of data loss or corruption THERE, and not during extraction:

Code: Select all

blank_image.readPixels(RGBQuantum, myMovie.getPixels() );
because i am feeding a 1 byte array by using myMovie.getPixels(); when readPixels is expecting 2 byte array.
right?
cuz if so, i can solve this, no need to recompile! geez why would you say that :(
Post Reply