1,該項目分析:git
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); }
//
另外理解下OffSet 的含義:
首先 定義了 OffSetPoint=元素左上角1-鼠標點擊1;
定義
元素左上角2=鼠標點擊2+OffSetPoint;
注意:OffSetPoint是相對於鼠標點擊的位置,因此,能夠所示 元素對應鼠標的偏移值,因此,元素位置2,能夠用 鼠標位置2+相對值來求出來.
能夠定義表達式 : 元素左上角2-元素左上角1=鼠標點擊2-鼠標點擊1;
二:效果
三:位圖:
格局格式決定每一個像素點的字節數:
其中 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 是 着色語言生成文件.