using PDF_Master.Helper; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace PDF_Master.CustomControl.ScanViewControl { public class CustomPanel : Panel { public SolidColorBrush CoverBrush { get; set; } = new SolidColorBrush(Color.FromArgb(0xCC, 0xFF, 0xFF, 0xFF)); public bool DrawCover { get; set; } = false; public Rect DrawRect { get; set; } private WriteableBitmap BackgroundImage = null; private int BackgroundWidth = 0; private int BackgroundHeight = 0; private Point OffsetPos = new Point(0, 0); private double ScaleRate = 1; private CustomDraw HoverChild = null; public TextBlock ParentBlock; private int RawWidth = 0; private int RawHeight = 0; /// /// 展示用的背景图 /// public WriteableBitmap BGImage { get { return (WriteableBitmap)GetValue(BGImageProperty); } set { SetValue(BGImageProperty, value); } } // Using a DependencyProperty as the backing store for BGImage. This enables animation, styling, binding, etc... public static readonly DependencyProperty BGImageProperty = DependencyProperty.Register("BGImage", typeof(WriteableBitmap), typeof(CustomPanel), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnImageChanged))); private static void OnImageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if ((e.NewValue as WriteableBitmap) != null) { (d as CustomPanel).SetBackgroundImage(e.NewValue as WriteableBitmap); } } /// /// 当前页的OCR结果 /// public List> OCRTextRectList { get { return (List>)GetValue(OCRTextRectListProperty); } set { SetValue(OCRTextRectListProperty, value); } } // Using a DependencyProperty as the backing store for OCRTextRectList. This enables animation, styling, binding, etc... public static readonly DependencyProperty OCRTextRectListProperty = DependencyProperty.Register("OCRTextRectList", typeof(List>), typeof(CustomPanel), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnOCRChanged))); private static void OnOCRChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if ((e.NewValue as List>) != null) { (d as CustomPanel).SetTextsRects(e.NewValue as List>); } } public bool IsShowRect { get { return (bool)GetValue(IsShowRectProperty); } set { SetValue(IsShowRectProperty, value); } } // Using a DependencyProperty as the backing store for IsShowRect. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsShowRectProperty = DependencyProperty.Register("IsShowRect", typeof(bool), typeof(CustomPanel), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnShowRectChanged))); private static void OnShowRectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (Convert.ToBoolean(e.NewValue)==false) { (d as CustomPanel).SetRect(new Rect(0,0,0,0)); (d as CustomPanel).RectDraw(); } } private List VisualControlList = new List(); private DrawRect RectObject { get; set; } = new DrawRect(); public CustomPanel() { AddLogicalChild(RectObject); AddVisualChild(RectObject); } protected override int VisualChildrenCount { get { return VisualControlList.Count + 1; } } protected override Visual GetVisualChild(int index) { if (index == VisualControlList.Count) { return RectObject; } return VisualControlList[index]; } protected override void OnRender(DrawingContext dc) { DrawRect = new Rect(0, 0, ActualWidth, ActualHeight); dc.DrawRectangle(Brushes.LightGray, null, DrawRect); DrawBackground(dc); } protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { double scale = Math.Min(sizeInfo.NewSize.Width / BackgroundWidth, sizeInfo.NewSize.Height / BackgroundHeight); int drawWidth = (int)(scale * BackgroundWidth); int drawHeight = (int)(scale * BackgroundHeight); if (drawWidth < 10 || drawHeight < 10) { return; } int offsetX = (int)((sizeInfo.NewSize.Width - drawWidth) / 2); int offsetY = (int)((sizeInfo.NewSize.Height - drawHeight) / 2); foreach (CustomDraw drawVisual in VisualControlList) { Rect paintRect = drawVisual.RawRect; drawVisual.PaintRect = new Rect((int)(paintRect.Left * scale + offsetX), (int)(paintRect.Top * scale + offsetY), (int)(paintRect.Width * scale), (int)(paintRect.Height * scale)); drawVisual.Draw(); } } private void DrawBackground(DrawingContext dc) { if (BackgroundImage != null && BackgroundWidth > 0 && BackgroundHeight > 0) { double scale = Math.Min(ActualWidth / BackgroundWidth, ActualHeight / BackgroundHeight); int drawWidth = (int)(scale * BackgroundWidth); int drawHeight = (int)(scale * BackgroundHeight); if (drawWidth < 10 || drawHeight < 10) { return; } ScaleRate = scale; OffsetPos.X = (int)((ActualWidth - drawWidth) / 2); OffsetPos.Y = (int)((ActualHeight - drawHeight) / 2); DrawRect = new Rect(OffsetPos.X, OffsetPos.Y, drawWidth, drawHeight); dc.DrawImage(BackgroundImage, DrawRect); if (DrawCover) { dc.DrawRectangle(CoverBrush, null, DrawRect); } } } private void CleanChild() { foreach (DrawingVisual child in VisualControlList) { RemoveLogicalChild(child); RemoveVisualChild(child); } VisualControlList.Clear(); } public void SetBackgroundImage(WriteableBitmap bgImage) { DrawCover = false; BackgroundImage = bgImage; BackgroundWidth = 0; BackgroundHeight = 0; RawWidth = 0; RawHeight = 0; OffsetPos = new Point(0, 0); CleanChild(); if (BackgroundImage != null && BackgroundImage.PixelHeight > 0 && BackgroundImage.PixelWidth > 0) { RawWidth = BackgroundImage.PixelWidth; RawHeight = BackgroundImage.PixelHeight; BackgroundWidth = DpiHelpers.GetDpiUnrelatedNum(BackgroundImage.PixelWidth); BackgroundHeight = DpiHelpers.GetDpiUnrelatedNum(BackgroundImage.PixelHeight); double scale = Math.Min(ActualWidth / BackgroundWidth, ActualHeight / BackgroundHeight); int drawWidth = (int)(scale * BackgroundWidth); int drawHeight = (int)(scale * BackgroundHeight); if (drawWidth < 10 || drawHeight < 10) { return; } ScaleRate = scale; OffsetPos.X = (int)((ActualWidth - drawWidth) / 2); OffsetPos.Y = (int)((ActualHeight - drawHeight) / 2); InvalidateVisual(); } } /// /// 设置绘制内容 /// public void DisplayContent(CustomDraw custom) { if (custom != null) { if (HoverChild == null) { HoverChild = custom; HoverChild.DrawBounds(); if (ParentBlock != null) { ParentBlock.Text = HoverChild.PaintText; } } else { if (HoverChild != custom) { HoverChild?.Draw(); HoverChild = custom; HoverChild.DrawBounds(); } } } else { if (HoverChild != null) { HoverChild.Draw(); HoverChild = null; } } } public int GetBackgroundImageWidth() { if (BackgroundImage != null) { return RawWidth; } return 0; } public int GetBackgroundImageHeight() { if (BackgroundImage != null) { return RawHeight; } return 0; } /// /// 设置文字与文字矩形 /// public void SetTextsRects(List> textsRect) { CleanChild(); foreach (KeyValuePair textRect in textsRect) { CustomDraw drawVisual = new CustomDraw(); drawVisual.PaintText = textRect.Value; Rect paintRect = DpiHelpers.GetDpiUnrelatedRect(textRect.Key); drawVisual.RawRect = paintRect; drawVisual.PaintRect = new Rect((int)(paintRect.Left * ScaleRate + OffsetPos.X), (int)(paintRect.Top * ScaleRate + OffsetPos.Y), (int)(paintRect.Width * ScaleRate), (int)(paintRect.Height * ScaleRate)); drawVisual.Draw(); VisualControlList.Add(drawVisual); AddLogicalChild(drawVisual); AddVisualChild(drawVisual); } } public void RePaint() { InvalidateVisual(); } public void SetRect(Rect newRect) { RectObject.SetRect(newRect); } public bool RectMouseMove(Point clickPoint) { return RectObject.MouseMove(clickPoint); } public bool RectMouseLeftButtonUp(Point clickPoint) { return RectObject.MouseLeftButtonUp(clickPoint); } public bool RectMouseLeftButtonDown(Point clickPoint) { return RectObject.MouseLeftButtonDown(clickPoint, this); } public void RectSetMaxRect(Rect rect) { RectObject.SetMaxRect(rect); } public void RectDraw() { RectObject.Draw(); } public void ClearDraw() { RectObject.ClearDraw(); } public Rect GetClientRect() { return RectObject.GetClientRect(); } } }