Copying block of pixels with ImageMagick

232 views Asked by At

I am doing an assignment in which I have to manually mirror an image. I've been able to use image.pixelColor() to copy each color from a pixel and swap it with a pixel color in other position to mirror the image. But I've been unsuccessfully trying to do it by copying one row/column (block) of pixels at time using other methods (getPixels, setPixels, readPixels, writePixels, syncPixels).

Just to learn how to use the methods, I've been trying to do something like this, to copy a 50x50 block from the original to the new image:

    Image original;
    original.read("original.png");
    Image new  ("300x300", "white");
    Quantum *block;
    unsigned char *buffer;

    original.modifyImage();    
    block = original.getPixels(0,0,50,50);//from image to pixel cache
    original.writePixels(Magick::RGBQuantum, buffer); //from image pixel cache to buffer, region set by getPixels()

    new.modifyImage();
    new.setPixels(50,50,50,50);//alocate pixel cache region
    new.readPixels(Magick::RGBQuantum, buffer); //from buffer to image pixel cache
    new.syncPixels(); //from image pixel cache to image

    original.display()
    new.display();

It's not working as "new" is shown white with a 50x50 black region.

1

There are 1 answers

0
Alexander On

the issue is in buffer and its usage in original.writePixels(Magick::RGBQuantum, buffer); writePixels saves data into buffer but it's not initialized in your case.

you should allocate some memory for the buffer:

Image original;
original.read("original.png");
Image newIm("300x300", "white");
PixelPacket *block;
std::vector<unsigned char> buffer(4 /* RGBA */ 
                                  * 2 /* 2 bytes per color*/  
                                  * 50 * 50 /* block size*/);

original.modifyImage();
block = original.getPixels(0, 0, 50, 50);
original.writePixels(Magick::RGBQuantum, buffer.data());
newIm.modifyImage();
newIm.setPixels(50, 50, 50, 50);
newIm.readPixels(Magick::RGBQuantum, buffer.data());
newIm.syncPixels();
original.display();
newIm.display();