简体   繁体   中英

How to copy the rgbalues to the pictureBox1 but one by one or each time a group of pixels?

private void pictureBox2_Paint(object sender, PaintEventArgs e)
        {
            Bitmap bmp = new Bitmap(pictureBox1.Image);

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                bmp.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
            byte[] rgbValues = new byte[bytes];

            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            // Set every third value to 255. A 24bpp bitmap will look red.  
            //for (int counter = 2; counter < rgbValues.Length; counter +=64)
              //  rgbValues[counter] = 255;

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

            // Unlock the bits.
            bmp.UnlockBits(bmpData);

            // Draw the modified image.
            e.Graphics.DrawImage(bmp, 0, 0);
        }

i mean to see in pictureBox2 the image get fill slowly like a paint get painted each time a bit. and not at once. with the original colors of the image in pictureBox1 to copy the image in pictureBox1 to pictureBox2 buti nstead in once to make it slowly and each time copy some pixels or one by one until the whole image paint is completed in pictureBox2.

I tried this.

in time tick event:

int cc = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            cc++;
            pictureBox2.Invalidate();
        }

in pictureBox2 paint event

private void pictureBox2_Paint(object sender, PaintEventArgs e)
        {
            Bitmap bmp = new Bitmap(pictureBox1.Image);

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                bmp.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.

            int bytes = Math.Abs(bmpData.Stride) * cc;//bmp.Height;
            byte[] rgbValues = new byte[bytes];

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

            // Unlock the bits.
            bmp.UnlockBits(bmpData);

            // Draw the modified image.
            e.Graphics.DrawImage(bmp, 0, 0);
        }

but the code in the pictureBox2 paint event delete the image in the pictureBox2 delete slowly from the top to the bottom.

but i want the opposite that it will start that the pictureBox2 is clear and then the image will be painted slowly.

i tried to change the line:

Bitmap bmp = new Bitmap(pictureBox1.Image);

to

Bitmap bmp = new Bitmap(512, 512);

but then it does nothing in the pictureBox2.

Here's an example that will copy the image line by line:

private async void button1_Click(object sender, EventArgs e)
{
    if (pictureBox1.Image != null)
    {
        button1.Enabled = false;

        Bitmap bmp1 = new Bitmap(pictureBox1.Image);
        Bitmap bmp2 = new Bitmap(bmp1.Width, bmp1.Height);
        pictureBox2.Image = bmp2;
        using (Graphics G = Graphics.FromImage(bmp2))
        {
            for (int y = 0; y < bmp1.Height; y++)
            {
                Rectangle rc = new Rectangle(new Point(0, y), new Size(bmp1.Width, 1));
                G.DrawImage(bmp1, rc, rc, GraphicsUnit.Pixel);
                pictureBox2.Invalidate();
                await Task.Delay(1);
            }                                                 
        }

        button1.Enabled = true;
    }
}

Sample run:

在此处输入图像描述

To make it go faster, you can increase the height of the rectangle being copied, and then make the for loop jump by that much:

int height = 12; // added
for (int y = 0; y < bmp1.Height; y = y + height) // change
{
    Rectangle rc = new Rectangle(new Point(0, y), new Size(bmp1.Width, height)); // change
    G.DrawImage(bmp1, rc, rc, GraphicsUnit.Pixel);
    pictureBox2.Invalidate();
    await Task.Delay(1);
}

Here's another approach showing a radial expansion using a GraphicsPath, Region, and a Clip:

private async void button2_Click(object sender, EventArgs e)
{
    if (pictureBox1.Image != null)
    {
        button2.Enabled = false;

        Bitmap bmp1 = new Bitmap(pictureBox1.Image);
        Bitmap bmp2 = new Bitmap(bmp1.Width, bmp1.Height);
        pictureBox2.Image = bmp2;
        int radius = Math.Max(bmp1.Width, bmp1.Height);
        Point center = new Point(bmp1.Width / 2, bmp2.Height / 2);
        using (Graphics G = Graphics.FromImage(bmp2))
        {
            int step = 10;
            for (int r=0; r <=radius; r=r+step)
            {                       
                Rectangle rc = new Rectangle(center, new Size(1, 1));
                rc.Inflate(r, r);
                using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
                {
                    gp.AddEllipse(rc);
                    using (Region rgn = new Region(gp))
                    {
                        G.Clip = rgn;
                        G.DrawImage(bmp1, 0, 0);
                    }
                }                        
                pictureBox2.Invalidate();
                await Task.Delay(1);
            }
        }

        button2.Enabled = true;
    }
}

Play with the step value to make it go faster or slower:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM