14—VisualDrawing

1,該項目分析:git

image

2,wpf佈局:數組

<Window x:Class="Drawing.VisualLayer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="VisualLayer" Height="350.4" Width="496.8"
        xmlns:local="clr-namespace:Drawing"
    >
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
      </Grid.ColumnDefinitions>
      <ToolBarTray Orientation="Vertical">
      <ToolBar>
        <RadioButton Margin="0,3" Name="cmdSelectMove">
          <StackPanel>
            <Image Source="pointer.png" Width="35" Height="35"></Image>
            <TextBlock>Select/Move</TextBlock>
          </StackPanel>
        </RadioButton>
        <RadioButton Margin="0,3" IsChecked="True" Name="cmdAdd">
          <StackPanel>
            <Rectangle Width="30" Height="30" Stroke="SteelBlue" StrokeThickness="3" Fill="AliceBlue"></Rectangle>
            <TextBlock>Add Square</TextBlock>
          </StackPanel>
        </RadioButton>
        <RadioButton Margin="0,3" Name="cmdDelete">
          <StackPanel>
            <Path Stroke="SteelBlue" StrokeThickness="4" StrokeEndLineCap="Round" StrokeStartLineCap="Round"
                  Fill="Red" HorizontalAlignment="Center">
              <Path.Data>
                <GeometryGroup>
                  <PathGeometry>
                    <PathFigure StartPoint="0,0">
                      <LineSegment Point="18,18"></LineSegment>
                    </PathFigure>
                    <PathFigure StartPoint="0,18">
                      <LineSegment Point="18,0"></LineSegment>
                    </PathFigure>
                  </PathGeometry>
                </GeometryGroup>
              </Path.Data>
            </Path>
            <TextBlock>Delete Square</TextBlock>
          </StackPanel>
        </RadioButton>
        <RadioButton Margin="0,3" Name="cmdSelectMultiple">
          <StackPanel>
            <Image Source="pointer.png" Width="35" Height="35"></Image>
            <TextBlock>Select Multiple</TextBlock>
          </StackPanel>
        </RadioButton>
      </ToolBar>
      </ToolBarTray>

      <Border Grid.Column="1" Margin="3" BorderBrush="SteelBlue" BorderThickness="1">

        <local:DrawingCanvas x:Name="drawingSurface" Background="White" ClipToBounds="True"
                             MouseLeftButtonDown="drawingSurface_MouseLeftButtonDown"
                MouseLeftButtonUp="drawingSurface_MouseLeftButtonUp"
                MouseMove="drawingSurface_MouseMove">
        </local:DrawingCanvas>


      </Border>
    </Grid>
</Window>

   建立了左右兩欄,1欄是工具欄,1欄是畫圖欄.編輯器

   右側建立畫圖對象.ide


1,添加圖形對象的邏輯:(必須設置背景顏色)工具

            1,生成VisualDrawing對象.而後添加到Canvas對象之中佈局

  private List<Visual> visuals = new List<Visual>();

        protected override Visual GetVisualChild(int index)
        {
            return visuals[index];
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return visuals.Count;
            }
        }

        public void AddVisual(Visual visual)
        {
            visuals.Add(visual);

            base.AddVisualChild(visual);
            base.AddLogicalChild(visual);
        }

        public void DeleteVisual(Visual visual)
        {
            visuals.Remove(visual);

            base.RemoveVisualChild(visual);
            base.RemoveLogicalChild(visual);
        }

     2 獲取VisualDrawing對象.而且刪除測試

  public DrawingVisual GetVisual(Point point)
        {
            HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
            return hitResult.VisualHit as DrawingVisual;
        }

        private List<DrawingVisual> hits = new List<DrawingVisual>();
        public List<DrawingVisual> GetVisuals(Geometry region)
        {
            hits.Clear();
            GeometryHitTestParameters parameters = new GeometryHitTestParameters(region);
            HitTestResultCallback callback = new HitTestResultCallback(this.HitTestCallback);
            VisualTreeHelper.HitTest(this, null, callback, parameters);
            return hits;
        }

        private HitTestResultBehavior HitTestCallback(HitTestResult result)
        {
            GeometryHitTestResult geometryResult = (GeometryHitTestResult)result;
            DrawingVisual visual = result.VisualHit as DrawingVisual;
            if (visual != null &&
                geometryResult.IntersectionDetail == IntersectionDetail.FullyInside)
            {
                hits.Add(visual);
            }
            return HitTestResultBehavior.Continue;
        }

命中測試:this

刪除操做:spa

 public void DeleteVisual(Visual visual)
        {
            visuals.Remove(visual);

            base.RemoveVisualChild(visual);
            base.RemoveLogicalChild(visual);
        }

  3,得到當前座標的當前位置值:.net

當獲取Visual的ContentBounds的時候,其實際上包含了一半的線寬:

Point curPos = new Point(visual.ContentBounds.TopLeft.X + pen.Thickness / 2, visual.ContentBounds.TopLeft.Y + pen.Thickness / 2);

4  ,如何繪製虛線框:

  首先根據選擇,在Down的時候,開始加入一個Visual對象

 else if (cmdSelectMultiple.IsChecked == true)
            {

                selectionSquare = new DrawingVisual();

                drawingSurface.AddVisual(selectionSquare);

                selectionSquareTopLeft = pointClicked;
                isMultiSelecting = true;

                // Make sure we get the MouseLeftButtonUp event even if the user
                // moves off the Canvas. Otherwise, two selection squares could be drawn at once.
                drawingSurface.CaptureMouse();
            }


,而後在移動的過程當中繪製該對象

if (isDragging)
            {
                Point pointDragged = e.GetPosition(drawingSurface) + clickOffset;
                DrawSquare(selectedVisual, pointDragged, true);
            }
            else if (isMultiSelecting)
            {
                Point pointDragged = e.GetPosition(drawingSurface);
                DrawSelectionSquare(selectionSquareTopLeft, pointDragged);
            }
l

//

另外理解下OffSet 的含義:

首先 定義了 OffSetPoint=元素左上角1-鼠標點擊1;

              定義

                     元素左上角2=鼠標點擊2+OffSetPoint;

注意:OffSetPoint是相對於鼠標點擊的位置,因此,能夠所示 元素對應鼠標的偏移值,因此,元素位置2,能夠用 鼠標位置2+相對值來求出來.

          能夠定義表達式  : 元素左上角2-元素左上角1=鼠標點擊2-鼠標點擊1;

二:效果

三:位圖:

  格局格式決定每一個像素點的字節數:

image

其中 Stride是每行佔用字節數的4的取整. 能夠使用 (Nums+3)/4*4來獲取.


32位RGB:假設X、Y爲位圖中像素的座標,則其在內存中的地址爲scan0+Ystride+X4。此時指針指向藍色,其後分別是綠色、紅色,alpha份量。
24位RGB:scan0+Ystride+X3。此時指針指向藍色,其後分別是綠色和紅色。
8位索引:scan0+Ystride+X。當前指針指向圖像的調色盤。
4位索引:scan0+Ystride+(X/2)。當前指針所指的字節包括兩個像素,經過高位和低位索引16色調色盤,其中高位表示左邊的像素,低位表示右邊的像素。
1位索引:scan0+Y*stride+X/8。當前指針所指的字節中的每一位都表示一個像素的索引顏色,調色盤爲兩色,最左邊的像素爲8,最右邊的像素爲0。

使用LockBits方法進行將Bitmap 轉換爲writebleBitmap的方式

 private  WriteableBitmap ConvertFromBitmap(System.Drawing.Bitmap bitmap)
        {
            var tt = bitmap;
          var   dt = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly,bitmap.PixelFormat);

            Byte* p = (Byte *)dt.Scan0;

            WriteableBitmap bitmap1 = new WriteableBitmap(bitmap.Width, bitmap.Height, 96, 96, PixelFormats.Bgra32, null);
            Int32Rect rect = new Int32Rect(0, 0, bitmap.Width, bitmap.Height);
            Byte[] pixels = new Byte[bitmap.Width * bitmap.Height * 4];

            for(var i=0;i<pixels.Length;i++)
            {
                pixels[i] = *(p + i);
            }
            bitmap.UnlockBits(dt);
            bitmap1.WritePixels(rect, pixels, dt.Stride, 0);
            pixels = null;
            return bitmap1;
        }


本質上操做位圖就是操做一個bytes數組.只要注意顏色.是按照(B,G,R,A)格式來就能夠了.


四 自定義效果以及實現 https://blog.csdn.net/WPwalter/article/details/90575912

1,下載並安裝軟件https://gitee.com/mao_qin_bin/download/tree/master/Shazzam

2,認識該編輯器:

.fx 是 着色語言生成文件.

相關文章
相關標籤/搜索