Page 1 of 1

Tiling an image (sequential crop/chop)

Posted: 2012-12-11T15:14:35-07:00
by Arutha123
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;

Re: Tiling an image (sequential crop/chop)

Posted: 2012-12-12T11:12:03-07:00
by Arutha123
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.