2017-03-24 23 views
0

我想在WinFrom应用程序中为pictureBox创建2个透明叠加,所以我可以分别在两者上绘图,并且我还可以在需要空白透明叠加时清除它。WinForms创建透明可清除图片框叠加

在一个覆盖图上画矩形。我总是希望这些矩形在那里。

在第二个覆盖图上绘制圆圈,但我只想绘制1个圆圈,并且在用户输入后清除此圆圈并绘制另一个圆圈。

现在我使用

var transparentOverlay = pictureBox.createGraphics(); 

但我不知道如何清除覆盖空白透明图形。 我试图

  1. transparentOverlay.Clear(Color.Transparent)这竟然全部覆盖黑色
  2. pictureBox.Invalidate()其清除从两个覆盖所有的图形,所以我的长方形保持他们在那里
  3. 使用我任何绘图之前创建一些备份的图形和清除我的叠加通过分配这个图形它transparentOverlay = transparentOverlayBackup但什么也没做,所有的矩形及各界保持在他们的地方

有没有一种方法来创建可清除ŧ ransparent图形坚持pictureBox?

编辑:

我有在图片框文字的图片。而我想要做的是围绕文本的文字绘制矩形,这个矩形应该始终保持在图片上。

比我想画一个圆圈,并等待用户点击一个屏幕。这一切都可以,但是当用户点击一个屏幕时,我想清除那个圆圈并画另一个圆圈。

first step show one circle second step after user click another circle show up but firs should disappear

//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

'Clear'只是手段,以填补颜色的一切。使用完全透明的墨水(或刷子或笔)不会改变任何东西。 – taffer

+0

附加信息:屏幕或控件的“图形”永远不会有透明区域。在将整个屏幕渲染为透明区域之后,您还期望什么?监视器上有一个洞?相反,“无”开始于黑色背景,你可以在其上绘制“某物”。不过,“位图”背景可以是透明的。 – taffer

+0

我忘了说,在Picturebox中我有一张图片(带有文字的截图)。而且,我想要的是在这张照片上设置透明区域,这样我就可以利用它。我有这样透明的区域,但问题是我想要永久性绘制某些东西(那些矩形),并且我想只是暂时的(这些圆形)。所以我认为我会创建两个透明的区域,但它的行为就像是一个区域。我希望一个区域被清除,另一个区域保持不变。 – Gondil

回答

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 

在上面的部分中,我创建了一个im的静态部分年龄,这将不会改变,我支持它,所以下一次我将创建新的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

你最好的办法是使用OnPaint事件处理程序PictureBox控件,把你所有的绘图调用在那里。

您可以使用传递给事件处理函数的Graphics对象来获取要绘制的曲面(即图片框),然后使用各种方法绘制后面的图形。

要绘制“透明”形状,只需绘制轮廓而不是填充形状。