Hello,

Once more, I'm having a problem which I've been breaking my head about for a few hours searching Google to no avail, and came here again for some consult about.

The thing is this; I have an image file, the size of 16x16 pixels, and I want to paint it into a larger image as to fill it up by repititions of this image, in my current code, I do it pixel by pixel, however, that only works for rather small images and makes my program crush when the size is too big.

I was hoping that there would be a solution into cropping out a bunch of pixels and pasting them as-is into another image, I then found that the function Clone does something like that, well, half of it anyway, I can crop a rectangle of the 16x16 pixels I want, however I can't find a way to paste them onto the other image.

Google search for about 2 hours brought no fruit, is this even possible?

Thanks to any and all answers.

Recommended Answers

All 7 Replies

Are you using Winforms or Win32? If Winforms, search on "GDI+ tiling an image" (some of the examples are for VB, but the syntax should be easy to translate to C++/CLI)

Are you trying to display it or do you need to save a copy out like that?

Winforms, and I need to both save and display it, I think the order of which is irrelevant, that is, if you mean by displaying it into a pictureBox?

And thanks very much for that direction, I need to head off to work now, so I can't tell you right now if I found it, but I'll come back to report as soon as I can, thanks alot.

Yes, the tiling is easier in a picturebox. I think you would be able to tile it on a picturebox (using the ImageLayout::Tile) then take the BackgroundImage as a new image and save it. I've never tried it like that, but it's worth a shot.

Ok, I'm really sorry about this, but I've spent the day trying to make it work from examples I found on Google searching for how paint by tiles like you suggested, though I really got nowhere on it.

void paintTile(int x, int y){
			FileStream ^fs = gcnew FileStream(umtm(project._p->it->pPath), 
				FileMode::Open);
			Bitmap^ bmp2 = gcnew Bitmap(fs);
			Graphics ^g = Graphics::FromImage(bmp2);

			g->DrawImage(tileDrawer, x*16, y*16);
			
			fs->Close();
			delete (IDisposable^) fs;
			bmp2 = gcnew Bitmap(bmp2->Size.Width, 
				bmp2->Size.Height, g);
			Image ^img = bmp2;
			pictureBox3->Image = img;
		}

This is the code I'm currently using, where tileDrawer is a bitmap image declared globally that contains the 16x16 tile I want to feed to the image.

When I run that, well, nothing happens, no image is loaded to the pictureBox, it stays blank, when I try to save the image from the picturebox to a file, it also shows as blank still, as if I'm not painting anything into the image in this function, could you please point me to what I am doing wrong here? Or peraphs, show me a whole example of the tiling method?

Also, just another simpler question; if I had commands to delete the data from the Image and Bitmap files I opened at the last 5 lines of the function, like I did with the Filestream right above them, it would result in a GDI+ exception of an invalid parameter, which kicks in, not at that point, but once the containing event ends.
Why is that?

Once again, thanks for the help so far.

Your code is close. I had forgotten about DrawImage. You need to put it in a loop:

const int width = 80; //from your own picture
const int height = 80; 
const int multiplier = 5; //how many across and down
Image ^ picture = Image::FromFile("<your path here>");
Bitmap ^bmp = gcnew Bitmap(width*multiplier,height*multiplier);
Graphics ^ g = Graphics::FromImage(bmp);
for (int i = 0;i<height*multiplier;i+=height)
{
    for(int j = 0;j<width*multiplier;j+=width)
    {							
  	g->DrawImage(snake,(float)j,(float)i); //since x is width and y is height
    }
}

I only tested the code with a square image over a square area, so I may have something backwards, but you get the idea.

Then you can set a picturebox to hold bmp (and there should be no problem saving that out to a file, either). One thing to check, add a border to your picturebox for testing purposes. If nothing shows up in the window, you are probably missing the Controls.Add(yourpbox); call after you've set all of the parameters of the picture box.

if I had commands to delete the data from the Image and Bitmap files I opened at the last 5 lines of the function, like I did with the Filestream right above them, it would result in a GDI+ exception of an invalid parameter

That one I'm not sure of. Are you trying to clean up your objects? Unless you are seriously squeezed for resources, let the garbage collector take care of it. In terms of the exceptions, other objects may be relying on the location of certain handles to the objects, but I couldn't tell you that for certain.

Thanks for your very much appreciated input, jonsca.

The thing is, the code you gave didn't really help me, as my problem wasn't the looping, which I have done looping the function call instead of the function content, but rather the dealing with the image itself.

My problem, apparently, was caused by using a null image from the pictureBox as the argument for the construction of the bmp, as the file opened by the filestream in the first line of my code had been saved to with no data, as it was just created.

The way I fixed this evantually, was by creating a Bitmap inside the function, that would only draw from the PictureBox if the image in it isn't null, and if it is, it would construct it with the size it needs to be then put it into the pictureBox for future use.

For future reference, this is the code I used that worked:

void paintTile(int x, int y){
			Bitmap^ bmp;
			if(pictureBox3->Image)
				bmp = gcnew Bitmap(pictureBox3->Image);
			else
				bmp = gcnew Bitmap(project._p->it->xTile, 
					project._p->it->yTile);
			Graphics^ g = Graphics::FromImage(bmp);
			g->DrawImage(tileDrawer, x, y);
			pictureBox3->Image = bmp;
		}

As for my other question from earlier, yes, I was trying to clean up the objects, as I've noticed while I was working pixel by pixel earlier, like I said, that on vast quantities of data to be processed, the system would just evantually crush unless I did the cleaning up myself, since it seemed that the garbage collector had failed me there.
I'm not squeezed for resources, but it would always be nice to have more at hand in the case I'll need to process a large number of tiles.

Well, once again, thanks for putting up with me for those last few days, jonsca, and hopefully, this could help more people in the future.

thanks for putting up with me for those last few days, jonsca

It was never a problem. Glad everything is up and running!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.