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
的颜色填充透明区域的原因。意思是,您需要将内部 PictureBox
的 Parent
属性 显式设置为外部
这是您 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;
}
}
这是结果。
我尝试将两张 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
的颜色填充透明区域的原因。意思是,您需要将内部 PictureBox
的 Parent
属性 显式设置为外部
这是您 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;
}
}
这是结果。