2017-03-24 11 views
0

WinFromアプリケーションのpictureBoxに2つの透明オーバーレイを作成したいので、両方を別々に描画することができ、透明オーバーレイを空にしたいときにクリアすることもできます。WinFormsは透明なクリア可能なpictureBoxオーバーレイを作成します

1つのオーバーレイで、長方形を描きます。私はこの四角形をいつも欲しいです。

2番目のオーバーレイでは円を描いていますが、1つの円を描きたいだけで、ユーザー入力後にこの円をクリアして別のサークルを描きたいだけです。

今の私は

var transparentOverlay = pictureBox.createGraphics(); 

を使用しています。しかし、私は空白の透明グラフィックにオーバーレイをクリアする方法を知りません。 私は、彼らが

  • 私は任意の描画前に作成され、いくつかのバックアップグラフィックスを使用して、私をクリアしたところ、私の矩形が残っているので、両方のオーバーレイからのすべてのグラフィックスをクリア黒
  • pictureBox.Invalidate()にすべてのオーバーレイを回し

    1. transparentOverlay.Clear(Color.Transparent)を試してみましたオーバーレイにこのグラフィックスを割り当てることでtransparentOverlay = transparentOverlayBackupこれは何もしませんでしたが、すべての四角形とすべての円がその場所に残ります

    クリア可能なtを作成する方法はありますか透明なグラフィックスは、pictureBoxに固執?

    EDIT:

    私はその画像ボックスのテキストと画像を持っています。そして、私がしたいことは、テキストの言葉の周りに長方形を描くことです。この長方形は常に絵の上に残っていなければなりません。

    私は単一の円を描き、ユーザーが画面をクリックするのを待っています。これはすべてOKですが、ユーザーが画面をクリックすると、その円をクリアして別のものを描きたいと思います。

    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に写真(テキスト付きのスクリーンショット)があると言って忘れました。そして、私が望むのは、この絵の上に透明な領域を設定することです、私はそれを描くことができます。私はそのような透明な領域を持っていますが、問題は、永久に描画されるもの(それらの四角形)と、一時的になりたいもの(それらの円)が欲しいということです。だから私は2つの透明な領域を1つずつ作成することを考えましたが、それは1つの領域のように動作します。 1つの領域をクリアし、もう1つの領域を同じにします。 – 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

    あなたの最善のアプローチは、PictureBoxコントロールのためのOnPaintイベントハンドラを使用して、そこにすべての描画呼び出しを置くことであろう。

    イベントハンドラに渡されたGraphicsオブジェクトを使用して、描画するサーフェス(つまりピクチャボックス)を取得し、さまざまな方法を使用して後のシェイプを描画できます。

    「透明な」形状を描くには、塗りつぶした形状ではなく輪郭を描きます。

    関連する問題