Search code examples
c#imagepicturebox

How to convert image to puzzle?


I Want the program get a pic of user ,then convert image to puzzle (for example 100 piece) then make 100 picture box.

I using this following code for 4 and 9 piece.

if (Image_Num.SelectedIndex == 0)
        {
            PB = new PictureBox[4];

            int W, H;
            var imgarray = new Image[4];
            var img = User_Image.Image;
            W = img.Width / 2;
            H = img.Height / 2;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    var index = i * 2 + j;
                    imgarray[index] = new Bitmap(W, H);
                    var graphics = Graphics.FromImage(imgarray[index]);
                    graphics.DrawImage(img, new Rectangle(0, 0, W, H), new Rectangle(i * W, j * H, W, H), GraphicsUnit.Pixel);
                    graphics.Dispose();
                }
            }

            PB[0] = new PictureBox
            {
                Name = "P1",
                Size = new Size(100, 100),
                Location = new Point(394, 60),
                Image = imgarray[0],
                SizeMode = PictureBoxSizeMode.StretchImage
            };
            ...

            PB[0].MouseEnter += Images_M_E;
            ...


            PB[0].MouseLeave += Images_M_L;
            ...


            PB[0].MouseClick += Images_C;
            ...

            Controls.Add(PB[0]);
            ...
        }

I can't do this for 100 times or more.

Thanks.


Solution

  • Here is an example: The code taken from your question with minimal changes to make it flexible; I have implemented the above comments but not gone beyond that.

    I hope you'll have fun studying it :-)

    private void SetUpPuzzle_Click(int parts)  // use the number of parts on each side
    {
        Control board = panel1;  // use the control you want to use or the form!
        int total = parts * parts;
        var PB = new PictureBox[total];
    
        var imgarray = new Image[total];
        var img = User_Image.Image;
        int W = img.Width / parts;
        int H = img.Height / parts;
        int size = 100;
        for (int x = 0; x < parts; x++)
        {
            for (int y = 0; y < parts; y++)
            {
                var index = x * parts + y;
                imgarray[index] = new Bitmap(W, H);
                using (Graphics graphics = Graphics.FromImage(imgarray[index]))
                    graphics.DrawImage(img, new Rectangle(0, 0, W, H), 
                                       new Rectangle(x * W, y * H, W, H), GraphicsUnit.Pixel);
                PB[index] = new PictureBox
                {
                    Name = "P"+ index,
                    Size = new Size(size, size),
                    Location = new Point(x * size, y * size),
                    Image = imgarray[index],
                    SizeMode = PictureBoxSizeMode.StretchImage
                };
                PB[index].MouseEnter += Images_M_E;
                PB[index].MouseLeave += Images_M_L;
                board.Controls.Add(PB[index]);
            }
        }
    }
    

    You can pass in any (reasonably small) number. You may also want to pass in the full image and you may want to make the size flexible; the 100x100 is the last magic number in the code. But all in your owm time..

    Here are two examples for common events that all pboxes can use:

    private void Images_M_E(object sender, EventArgs e)
    {
        PictureBox pb = sender as PictureBox;  // here we get a reference to the actual pbox
        pb.BorderStyle = BorderStyle.FixedSingle;   // do what you..
    }
    private void Images_M_L(object sender, EventArgs e)
    {
        PictureBox pb = sender as PictureBox;
        pb.BorderStyle = BorderStyle.None;   // ..want to do here
    }
    

    I left the code pretty much as it was; this means that not all issues are resolved. There is no obvious need for the arrays, really. The created images and pboxes are both added where they belong; no need to hold extra references in the arrays, which will go out of scope anyway after the code has run through.

    Also your spelling of variables is a bit confused. All private filed should be camelCase, so you do not capitalize the first letter! Properties and Classes are PascalCase. Basically nothing should consist of consecutive caps (as I saw in your previous posts.)