我想在WinFrom应用程序中为pictureBox创建2个透明叠加层,这样我就可以单独绘制两者,当我想要空白透明叠加层时我也可以清除它。
在一个叠加上我绘制矩形。我一直想要这些矩形。
在第二个叠加层上我绘制圆圈,但我只想绘制1个圆圈,在用户输入后清除此圆圈并绘制另一个圆圈。
现在我正在使用
var transparentOverlay = pictureBox.createGraphics();
但我不知道如何清除叠加到空白透明图形。 我试过了
transparentOverlay.Clear(Color.Transparent)
将所有叠加层变为黑色pictureBox.Invalidate()
清除了两个叠加层中的所有图形,因此我的矩形保持原位transparentOverlay = transparentOverlayBackup
来清除我的叠加层,但这没有做任何事情,所有矩形和所有圆圈都保留在它们的位置有没有办法创建贴在pictureBox上的可清晰透明图形?
修改
我在该图片框中有一张带文字的图片。我想要做的是在文本的单词周围绘制矩形,这个矩形应该一直保留在图片上。
比我想绘制一个圆圈并等待用户点击屏幕。这一切都还可以,但是当用户点击屏幕时,我想要清除那个圆圈并绘制另一个圆圈。
//this method I call by click on a button to start annotation
private void ExpertAnnotate(object sender, EventArgs e)
{
var pen = new Pen(Color.Black, 1);
if (!annotationIsRunning) //check if annotation is in process or not
{
annotationIsRunning = true;
annotationOverlay = pictureBox.CreateGraphics(); //create transparent overlay for drawing
//draw rectangles around all words in text (AOIs)
annotationAOIs.ForEach(a =>
{
annotationOverlay.DrawRectangle(pen, a.Start.X, a.Start.Y, (a.End.X - a.Start.X), (a.End.Y - a.Start.Y));
});
//subscribe mouseMove and mouseClick events on pictureBox
pictureBox.MouseMove += HighlightAOI;
pictureBox.MouseClick += SelectAOI;
}
//define brushes for drawing circles (fixations)
var brush = new SolidBrush(Color.FromArgb(128, Color.BlueViolet));
var dotBrush = new SolidBrush(Color.DarkBlue);
pen.Color = Color.Blue;
long sizeOfFixation;
var f = Fixations[fixationCounter - 1]; //get current fixation to draw
sizeOfFixation = (int)f.Length / FIX_SIZE_COEFICIENT; //compute size of circle
annotationOverlay.FillEllipse(dotBrush, f.PosX - 1, f.PosY - 1, 3, 3);
//draw fixation on overlay
annotationOverlay.FillEllipse(brush, (f.PosX - sizeOfFixation), (f.PosY - sizeOfFixation), sizeOfFixation * 2, sizeOfFixation * 2);
}
//eventHandler for mouseMove - this method color rectangle over which mouse hover to red border
private void HighlightAOI(object sender, EventArgs e)
{
//this just draw last highlighted rect to black when we not yet hover mouse above it
if (lastHighlightedAOI != null)
{
annotationOverlay.DrawRectangle(new Pen(Color.Black, 1), lastHighlightedAOI.Start.X, lastHighlightedAOI.Start.Y, (lastHighlightedAOI.End.X - lastHighlightedAOI.Start.X), (lastHighlightedAOI.End.Y - lastHighlightedAOI.Start.Y));
}
//get position of mouse sursor
var x = pictureBox.PointToClient(Cursor.Position).X;
var y = pictureBox.PointToClient(Cursor.Position).Y;
var tempFix = new Fixation() { PosX = x, PosY = y };
//get rectangle over which mouse hover
lastHighlightedAOI = tempFix.LiesIn(annotationAOIs).FirstOrDefault();
if (lastHighlightedAOI != null)
{
//highlight rectangle by painting red border
annotationOverlay.DrawRectangle(new Pen(Color.Red, 1), lastHighlightedAOI.Start.X, lastHighlightedAOI.Start.Y, (lastHighlightedAOI.End.X - lastHighlightedAOI.Start.X), (lastHighlightedAOI.End.Y - lastHighlightedAOI.Start.Y));
}
}
//eventHandler for mouse click
private void SelectAOI(object sender, EventArgs e)
{
//get position of cursor
var x = MousePosition.X;
var y = MousePosition.Y;
var tempFix = new Fixation() { PosX = x, PosY = y };
//get rectangle which we selected by a mouse click
var aoi = tempFix.LiesIn(annotationAOIs).FirstOrDefault();
//assign last shown fixation to selected rectangle
if (aoi != null)
{
aoi.AssignedFixations.Add(Fixations[fixationCounter - 1]);
}
//if it wasn't last fixation again call ExpertAnnotation function to draw another Fixation over image (!!! here I need to clear last drawn fixation (circle) disappear and draw next fixation in ExpertAnnotate method)
if (fixationCounter != Fixations.Count)
{
ExpertAnnotate(sender, e);
}
else
{
TerminateExpertAnnotation("regular");
}
}
答案 0 :(得分:0)
感谢@Reza Aghaei指导我聊天解决方案。
对我来说,可接受的解决方案是构建多层图像并将其分配给pictureBox.Image属性。
我通过从文件中加载图片来构建图像:
Image im = new Bitmap(path); // loads image from file
然后从此图像创建图形:
var g = Graphics.FromImage(im); // creates graphics from loaded image
将所有需要的矩形绘制到此图像,并将此图像备份到某个全局Image
实例:
var pen = new Pen(Color.Black, 1);
// draws all rectangles on the image
annotationAOIs.ForEach(a =>
{
g.DrawRectangle(pen, a.Start.X, a.Start.Y, (a.End.X - a.Start.X), (a.End.Y - a.Start.Y));
});
g.Dispose(); // disposes used graphics
ImageBackup = new Bitmap(im); // backup image with rectangles
在上面的部分中,我创建了一个静态的图像部分,它不会改变,我会备份它,所以下次我将从备份中创建新的Image
实例,而不需要任何矩形绘图。
然后当我想在这张图片上显示新的圆圈时,我只是:
var image = new Bitmap(ImageBackup); // creates new instance of image with rectangles from backup
var g = Graphics.FromImage(image); // creates graphics from image
// in this part draw circle at specific point
var f = Fixations[fixationIndex];
sizeOfFixation = (int)f.Length / FIX_SIZE_COEFICIENT;
g.FillEllipse(dotBrush, f.PosX - 1, f.PosY - 1, 3, 3);
g.FillEllipse(brush, (f.PosX - sizeOfFixation), (f.PosY - sizeOfFixation), sizeOfFixation * 2, sizeOfFixation * 2);
pictureBox.Image.Dispose(); // dispose old pictureBox image
pictureBox.Image = image; // set new image
imageOverlay = pictureBox.CreateGraphics(); // get transparent graphics overlay for pictureBox so we can draw anything else over picture (in my case highlighting rectangles over which I hover a mouse)
g.Dispose(); // dispose used graphics
答案 1 :(得分:-1)
您最好的方法是使用PictureBox控件的OnPaint事件处理程序,并将所有绘图调用放在那里。
您可以使用传递给事件处理程序的Graphics对象来获取要绘制的表面(即图片框),然后使用各种方法绘制您所追求的形状。
画一个透明的'形状只是绘制轮廓而不是填充形状。