Tiling an image (sequential crop/chop)

Magick++ is an object-oriented C++ interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick++.
Post Reply
Arutha123
Posts: 2
Joined: 2012-12-11T15:02:38-07:00
Authentication code: 6789

Tiling an image (sequential crop/chop)

Post by Arutha123 » 2012-12-11T15:14:35-07:00

Hi,

I'm trying to chop my image into X x Y tiles. But i cannot find a way to do it effeciently. Bellow is the code. The first loop works (the 0,0 tile is created) but the next loop will fail.
My guess is that the image data is not copied each loop and that the crop has broken the 'original' image data in the first loop. (in the pdf tutorial they say to use the copy constructor to achieve this? I assume this is wrong).

I think that reading the image each time will make the code work but this is most likely the most inefficient way. I was able to achieve the wanted effect using the core library but i want to stick to the ++ for maintainance (the c is just to ugly :D ).

Is there some way to make this work without reading from file every time? I already tried dumping the image in a blob after reading and constructing the image in the loop from this data but this also fails (not tested an explecit read call, just the constructor).

Code: Select all

	std::vector<Poco::Path> result;

	const Poco::Path targetFolder = target.isAbsolute() ? target : Poco::Path(location.current(), target);
	const Poco::Path locationFile = location.isAbsolute() ? location : Poco::Path(location.current(), location);

	const std::string extension = location.getExtension();
	std::string filename = location.getFileName();
	filename = filename.substr(0, filename.length() - extension.length() - 1);

	Magick::Image image;
	try
	{
		// Read a file into image object
		image.read(locationFile.toString());

		//TODO we might lose a pixel ... but images with uneven pixels are not common? (does not matter for now)
		int sizeHeight = (int)((float)image.rows() / (float)tileY);
		int sizeWidth = (int)((float)image.columns() / (float)tileX);

		for(int i = 0; i < tileY; i++)
		{
			for(int j = 0; j < tileX; j++)
			{
				Magick::Image currentcrop(image);
				std::stringstream ss;
				ss << filename << i*tileX + j << "." << location.getExtension();
				Poco::Path cur(targetFolder, ss.str());
				result.push_back(cur);

				currentcrop.crop(Magick::Geometry(sizeWidth,sizeHeight, sizeWidth*j, sizeWidth*i,false,false));
				currentcrop.write(cur.toString());
			}
		}
	}
	catch (Magick::Exception &error)
	{
		throw ESException(error);
	}
	return result;

Arutha123
Posts: 2
Joined: 2012-12-11T15:02:38-07:00
Authentication code: 6789

Re: Tiling an image (sequential crop/chop)

Post by Arutha123 » 2012-12-12T11:12:03-07:00

The code seems to be correct, i think my calculation of the crop rectangle was not correct.
It works now so i can move on.

Post Reply