簡體   English   中英

如何將 rgbalues 復制到 pictureBox1 但一個一個或每次一組像素?

[英]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);
        }

我的意思是在 pictureBox2 中看到圖像慢慢填充,就像每次都塗上油漆一樣。 而且不是一下子。 用pictureBox1中圖片的原始colors將pictureBox1中的圖片復制到pictureBox2中,但不是一次慢慢復制,每次復制一些像素或一張一張,直到整個圖像在pictureBox2中繪制完成。

我試過了。

在時間刻度事件中:

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

在 pictureBox2 繪畫事件中

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);
        }

但是pictureBox2 paint事件中的代碼delete pictureBox2中的圖片從上到下慢慢刪除。

但我想要相反的是,它會開始 pictureBox2 是清晰的,然后圖像會慢慢繪制。

我試圖改變這一行:

Bitmap bmp = new Bitmap(pictureBox1.Image);

Bitmap bmp = new Bitmap(512, 512);

但隨后它在 pictureBox2 中什么也不做。

這是一個逐行復制圖像的示例:

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;
    }
}

樣本運行:

在此處輸入圖像描述

為了使其 go 更快,您可以增加被復制矩形的高度,然后使 for 循環跳轉該高度:

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);
}

這是使用 GraphicsPath、Region 和 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;
    }
}

調整步長值使其 go 更快或更慢:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM