C# 位图旋转透明图像

C# Bitmap rotate with transparent image

我尝试将两张 png 图像放在一起。那些正在通过代码轮换如下。

private Bitmap RotateImage(Bitmap bmp, float angle)
        {
            Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height);
            rotatedImage.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);

            using (Graphics g = Graphics.FromImage(rotatedImage))
            {
                g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
                g.RotateTransform(angle);
                g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
                g.DrawImage(bmp, new Point(0, 0));            }

            return rotatedImage;
        }

但是,即使select图片的背景是透明的,显示窗体的背景色也是前面图片的背景色。我试图添加一个代码来绘制控件 as

e.Graphics.DrawImage(bmp, 50, 50, 100, 100);

但是当函数returns新的位图。它不工作。我该怎么做呢? Current Result.

完整代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Testing
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Bitmap bmp;
        Bitmap bmp1;
        Bitmap bmp2;
        public float angle = 10;
        public float rangle = 0;
        PaintEventArgs e;

        private void btn_Rotate_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private Bitmap RotateImage(Bitmap bmp, float angle)
        {
            Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height);
            rotatedImage.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);

            using (Graphics g = Graphics.FromImage(rotatedImage))
            {
                // Set the rotation point to the center in the matrix
                g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
                // Rotate
                g.RotateTransform(angle);
                // Restore rotation point in the matrix
                g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
                // Draw the image on the bitmap
                g.DrawImage(bmp, new Point(0, 0));

                bmp.MakeTransparent();
            }

            return rotatedImage;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // C:\Users\samsng\Desktop\left_right.png
            try
            {
                bmp = (Bitmap)Bitmap.FromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Pics/123.png"));
                bmp1 = (Bitmap)Bitmap.FromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Pics/3.png"));
                bmp2 = (Bitmap)Bitmap.FromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Pics/4.png"));

                pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
                pictureBox2.Image = bmp;
                pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
                pictureBox1.Image = bmp1;                
                pictureBox3.SizeMode = PictureBoxSizeMode.StretchImage;
                pictureBox3.Image = bmp2;
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("File Not Found Exception");
            }
            lblNum.Visible = false;
        }
        int time = 01;
        private void timer1_Tick(object sender, EventArgs e)
        {
            int i = 1;
            if (bmp != null)
            {
                pictureBox1.Image = RotateImage(bmp1, angle);
                pictureBox3.Image = RotateImage(bmp2, rangle);
                pictureBox2.Image = RotateImage(bmp, angle);
                angle += 10;
                rangle -= 10;
            }
            i++;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            lblNum.Visible = true;
            timer2.Start();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            if (time < 10)
            {
                lblNum.Text = "0" + time.ToString();
            }
            else
            {
                lblNum.Text = time.ToString();
            }
            time++;
            if (time == 99)
            {
                time = 01;
            }
        }

        private void pictureBox3_Paint(object sender, PaintEventArgs e)
        {
            //MessageBox.Show(e.ToString());
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            //e.Graphics.DrawImage(bmp1, 50, 50, 100, 100);
        }
    }
}

您有两个 PictureBox 控件,布局如下:

PictureBox 托管控件并不意味着它默认成为它们的父控件,因为它不像 Panel 或 [=] 那样是 容器 控件14=]。托管控件的父级仍然是托管 PictureBox 本身的父级,在您的情况下是 Form。这就是为什么内部 PictureBox 使用其父级 Form 的颜色填充透明区域的原因。意思是,您需要将内部 PictureBoxParent 属性 显式设置为外部

这是您 Form 中的相关代码,并进行了必要的更改。

public partial class Form1 : Form
{
    private Bitmap bmp, bmp1, bmp2;
    private float angle;

    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        try
        {
            bmp = Image.FromFile(Path.Combine(Application.StartupPath, 
                @"Pics3.png")) as Bitmap;
            bmp1 = Image.FromFile(Path.Combine(Application.StartupPath, 
                @"Pics.png")) as Bitmap;
            bmp2 = Image.FromFile(Path.Combine(Application.StartupPath, 
                @"Pics.png")) as Bitmap;

            pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox2.Image = new Bitmap(bmp);
            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox1.Image = new Bitmap(bmp1);
            pictureBox3.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox3.Image = new Bitmap(bmp2);

            // The fix
            pictureBox3.Location = pictureBox1.PointToClient(pictureBox3
                .PointToScreen(Point.Empty));
            pictureBox3.Parent = pictureBox1;
        }
        catch (FileNotFoundException)
        {
            MessageBox.Show("File Not Found Exception");
        }
    }

    // You should clean up!
    protected override void OnFormClosed(FormClosedEventArgs e)
    {
        base.OnFormClosed(e);

        bmp?.Dispose();
        bmp1?.Dispose();
        bmp2?.Dispose();

        pictureBox1.Image?.Dispose();
        pictureBox2.Image?.Dispose();
        pictureBox3.Image?.Dispose();
    }

    private void btn_Rotate_Click(object sender, EventArgs e)
    {
        timer1.Enabled = !timer1.Enabled;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        // You should dispose of the current images before setting new ones.
        pictureBox1.Image?.Dispose();
        pictureBox2.Image?.Dispose();
        pictureBox3.Image?.Dispose();

        pictureBox1.Image = RotateImage(bmp1, angle);
        pictureBox3.Image = RotateImage(bmp2, -angle);
        pictureBox2.Image = RotateImage(bmp, angle);
        angle += 10;
        if (angle >= 360) angle = 0;
    }

    private Bitmap RotateImage(Bitmap bmp, float angle)
    {
        Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height);
        rotatedImage.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);

        using (Graphics g = Graphics.FromImage(rotatedImage))
        {
            g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
            g.RotateTransform(angle);
            g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
            g.DrawImage(bmp, Point.Empty);
        }

        return rotatedImage;
    }
}

这是结果。