Modify image after writing to the disk fail (Magick++)

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
SwimmingElephant
Posts: 1
Joined: 2013-05-11T03:30:30-07:00
Authentication code: 6789

Modify image after writing to the disk fail (Magick++)

Post by SwimmingElephant »

Hi, I'm desperately in need of help. Can someone please tell me what's the stupid thing I'm doing in below?
It compiles and writes to the disk.
But two png files created are identical.

Code: Select all

#include "Magick++.h"
#include <unistd.h>
#include <iostream>
using namespace Magick;
using namespace std;

int main(int v, char** args){
	//Get the path to this executable
	ssize_t pathLength;
	char buffer[1024];
	string path;

	pathLength=readlink("/proc/self/exe",
		buffer,sizeof(buffer)-1);
		if(pathLength!=-1){
			buffer[pathLength]='\n';
			cout<<"Path to the executable: "<<buffer<<endl;
			InitializeMagick(buffer);
		}
		path=buffer;
		path=path.substr(0,path.length()-7);
		/////////////////////////////

		Image image(Geometry(500,500),
				Color(MaxRGB,MaxRGB,MaxRGB,0));

		image.modifyImage();
		Pixels view(image);
		PixelPacket* pixels=view.get(5,5,200,100);
		for(int c=0;c<1000;c++,pixels++){
			*pixels=Color("red");
		}
		view.sync();

		string outPath=path+string("/original.png");
		image.write(outPath);

        image.modifyImage();
        Pixels newView(image);
        pixels=newView.get(0,0,100,100);
        for(int c=0;c<1000;c++){
        	*pixels=Color("black");
        	pixels++;
        }
		newView.sync();
		image.syncPixels();
        outPath=path+string("/newImage.png");
        cout<<outPath<<endl;
        image.write(outPath);

			return 0;
}
I've tried something more complex too.
1)made a Image
2)made a copy of the image
3)modified the copy and saved on the disk
4)re-modified the copy ans saved on the disk
5)saved the original.
Result: the original image remains unaffected by the modifications made to its copies and fine.
(3) is fine too. But (4) produces an image identical to (3), where it's supposed to be different.

It seems once an Image object calls write() method, the image rejects all modifications made to itself.
Also calling write() on the original image object before on its copies, renders its copies unmodifiable as well.

Code: Select all

#include "Magick++.h"
#include <unistd.h>
#include <iostream>
using namespace Magick;
using namespace std;

int main(int v, char** args){
	//Get the path to this executable
	ssize_t pathLength;
	char buffer[1024];
	string path;

	pathLength=readlink("/proc/self/exe",
		buffer,sizeof(buffer)-1);
		if(pathLength!=-1){
			buffer[pathLength]='\n';
			cout<<"Path to the executable: "<<buffer<<endl;
			InitializeMagick(buffer);
		}
		path=buffer;
		path=path.substr(0,path.length()-7);
		/////////////////////////////

		Image image(Geometry(500,500),
				Color(MaxRGB,MaxRGB,MaxRGB,0));

		image.modifyImage();
		Pixels view(image);
		PixelPacket* pixels=view.get(5,5,200,100);
		for(int c=0;c<1000;c++,pixels++){
			*pixels=Color("red");
		}
		view.sync();
		string outPath=path+string("/original.png");
		//Calling image.write make the image and its copies
		//unmodifiable
		//uncommenting the below cause this program to produce
		//identical png files with just different names.
		//image.write(outPath);
////////////////////////////////////////////
        image.modifyImage();
        Pixels newView(image);
        PixelPacket* newPixels=newView.get(0,0,100,100);
        for(int c=0;c<1000;c++){
        	*newPixels=Color("yellow");
        	newPixels++;
        }
		newView.sync();
		image.syncPixels();

        Image iCopy(image);
        iCopy.modifyImage();
        Pixels sView(iCopy);
        pixels=sView.get(0,0,100,80);
        for(int c=0;c<50;c++,pixels++){
        	*pixels=Color("green");
        }
        sView.sync();
        iCopy.syncPixels();
        //sCopyI.write() working if image.write not
        //called prior to this point.
        outPath=path+string("/copiedImage.png");
        cout<<outPath<<endl;
        iCopy.write(outPath);


        //the original image remains unaffected by the
        //modification made to its copies.
		image.modifyImage();

        outPath=path+string("/OriginalImage.png");
        cout<<outPath<<endl;
        image.write(outPath);

        //Not working because iCopy has written to the disk
        //once.
		iCopy.modifyImage();
        pixels=sView.get(0,0,100,80);
               for(int c=0;c<50;c++,pixels){
               	*pixels=Color("black");
               }
               sView.sync();
        outPath= path + string("/copiedImageModified.png");
        cout<<outPath<<endl;
        iCopy.write(outPath);



	return 0;
}
I'm compiling with fedora16 witch is running on a vmware.
Version: ImageMagick 6.8.5-4 2013-05-03 Q16
ImageMagick has been compiled from source with
./configure
make
make install

function Image::pixelColor(long int, long int, Color()) seems to work fine.
I could avoid using PixelPacket array and Pixels entirely.
But if what I'm getting is not a result of my stupidity, maybe Magick++ does not like my environment and I should look for other options.
Post Reply