トップ回答者
picturebox背景が透明するため、どのようにするか

質問
-
Formにパネルを配置します。
パネルにカメラのLIVE画像を常に表示します。
画像の表面に直線を描画したいため、パネルの上にPICTUREBOXを貼り付け、背景を透明を設定しました。
PictureBoxに線を描きしました。
背景は透明になりません。
どうすれば透明になれますか?教えてください。
テストのコート(Live 画像はjpgファイルを代替しました)を下記のように書きました。
public partial class Form1 : Form
{
Bitmap bmpLine;
Bitmap bmpImage;
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.pictureBox1.BackColor = Color.Transparent;
}
private void Form1_Load(object sender, EventArgs e)
{
bmpLine = new Bitmap(this.Width, this.Height);
Graphics g= Graphics.FromImage(bmpLine);
g.DrawLine(new Pen(Color.Red, 2), 0, 0, bmpLine.Width, bmpLine.Height);
bmpLine.MakeTransparent();
bmpImage = new Bitmap("../../../\\Image\\img9.jpg");
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawImage(bmpLine, 0, 0, pictureBox1.Width, pictureBox1.Height);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics g = panel1.CreateGraphics();
g.DrawImage(bmpImage, 0, 0, panel1.Width, panel1.Height);
}
}実行すると
困っています。
よろしくお願いします。
回答
-
提示されているコードだとPanelのペイントイベントで本来描画しなければいけないGraphics以外に描画してしまっていますね。
using System; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { Bitmap bmpLine; Bitmap bmpImage; Panel panel1; PictureBox pictureBox1; public Form1() { //InitializeComponent(); pictureBox1 = new PictureBox(); pictureBox1.Left = 20; pictureBox1.Top = 30; pictureBox1.Width = 100; pictureBox1.Height = 100; pictureBox1.BackColor = Color.Transparent;//pictureBoxの背景を透過 pictureBox1.Paint+=pictureBox1_Paint; panel1 = new Panel(); panel1.Dock = DockStyle.Fill; panel1.Paint+=panel1_Paint; //PictureBoxをPanelの子にすることでpictureboxの透過先をpanelにする panel1.Controls.Add(pictureBox1); this.Controls.Add(panel1); panel1.BringToFront(); this.panel1.Controls.Add(pictureBox1); this.Padding = new Padding(30); this.Load += Form1_Load; this.BackColor = Color.Green; } private void Form1_Load(object sender, EventArgs e) { bmpLine = new Bitmap(this.Width, this.Height); using (Graphics g = Graphics.FromImage(bmpLine))//Graphicsを新しく作ったらDisposeする { g.DrawLine(new Pen(Color.Red, 2), 0, 0, bmpLine.Width, bmpLine.Height); } bmpLine.MakeTransparent(); bmpImage = new Bitmap("../../../\\Image\\img9.jpg"); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { if (bmpLine != null) { Graphics g = e.Graphics; g.DrawImage(bmpLine, 0, 0, pictureBox1.Width, pictureBox1.Height); } } private void panel1_Paint(object sender, PaintEventArgs e) { if (bmpImage != null) { //Graphics g = panel1.CreateGraphics(); Graphics g = e.Graphics; //新しくCreateGraphicsせずにPaintEventArgsのGraphicsを使うこと g.DrawImage(bmpImage, 0, 0, panel1.Width, panel1.Height); } } } }
#線を引くだけならPanelのペイントイベントでDrawImageの後ろに線を描画するコードでもいいと思いますが。個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク p-g-s-z 2015年11月10日 4:50
すべての返信
-
こんにちは。
Live画像云々の話があるので気になっているのですが、
画像はPaintで描画をしてやる必要があるのでしょうか。結局WinFormsにおける透過は、親の背景を描画するだけだと思うので、
透過させて画像を表示させるのであれば親の背景に画像を設定しなければいけないのかなと思うんです。private void Form1_Load(object sender, EventArgs e) { bmpLine = new Bitmap(this.Width, this.Height); Graphics g = Graphics.FromImage(bmpLine); g.DrawLine(new Pen(Color.Red, 2), 0, 0, bmpLine.Width, bmpLine.Height); bmpLine.MakeTransparent(); bmpImage = new Bitmap(filePath); //[Add] panel1.BackgroundImage = bmpImage; panel1.BackgroundImageLayout = ImageLayout.Stretch; } private void pictureBox1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.DrawImage(bmpLine, 0, 0, pictureBox1.Width, pictureBox1.Height); } private void panel1_Paint(object sender, PaintEventArgs e) { //[Delete] //Graphics g = panel1.CreateGraphics(); //g.DrawImage(bmpImage, 0, 0, panel1.Width, panel1.Height); }
あとは、あくまでDrawImageで画像を描画するのであれば、
pictureBox1のRegionでPictureBox自体を切り抜いてしまうか。#出来るのであればWPFで実装してやると悩まなくて済むかもしれません。
-
提示されているコードだとPanelのペイントイベントで本来描画しなければいけないGraphics以外に描画してしまっていますね。
using System; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { Bitmap bmpLine; Bitmap bmpImage; Panel panel1; PictureBox pictureBox1; public Form1() { //InitializeComponent(); pictureBox1 = new PictureBox(); pictureBox1.Left = 20; pictureBox1.Top = 30; pictureBox1.Width = 100; pictureBox1.Height = 100; pictureBox1.BackColor = Color.Transparent;//pictureBoxの背景を透過 pictureBox1.Paint+=pictureBox1_Paint; panel1 = new Panel(); panel1.Dock = DockStyle.Fill; panel1.Paint+=panel1_Paint; //PictureBoxをPanelの子にすることでpictureboxの透過先をpanelにする panel1.Controls.Add(pictureBox1); this.Controls.Add(panel1); panel1.BringToFront(); this.panel1.Controls.Add(pictureBox1); this.Padding = new Padding(30); this.Load += Form1_Load; this.BackColor = Color.Green; } private void Form1_Load(object sender, EventArgs e) { bmpLine = new Bitmap(this.Width, this.Height); using (Graphics g = Graphics.FromImage(bmpLine))//Graphicsを新しく作ったらDisposeする { g.DrawLine(new Pen(Color.Red, 2), 0, 0, bmpLine.Width, bmpLine.Height); } bmpLine.MakeTransparent(); bmpImage = new Bitmap("../../../\\Image\\img9.jpg"); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { if (bmpLine != null) { Graphics g = e.Graphics; g.DrawImage(bmpLine, 0, 0, pictureBox1.Width, pictureBox1.Height); } } private void panel1_Paint(object sender, PaintEventArgs e) { if (bmpImage != null) { //Graphics g = panel1.CreateGraphics(); Graphics g = e.Graphics; //新しくCreateGraphicsせずにPaintEventArgsのGraphicsを使うこと g.DrawImage(bmpImage, 0, 0, panel1.Width, panel1.Height); } } } }
#線を引くだけならPanelのペイントイベントでDrawImageの後ろに線を描画するコードでもいいと思いますが。個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク p-g-s-z 2015年11月10日 4:50