亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

WPF圖像在畫布上平移,縮放和滾動圖層

WPF圖像在畫布上平移,縮放和滾動圖層

白衣染霜花 2019-11-30 14:14:08
我希望有人可以在這里幫助我。我正在構建一個WPF成像應用程序,該應用程序從照相機中獲取實時圖像,從而允許用戶查看圖像,并隨后突出顯示該圖像上的關注區域(ROI)。然后將有關ROI的信息(寬度,高度,相對于圖像上某個點的位置等)發送回相機,實際上是告訴/培訓相機固件在哪里尋找諸如條形碼,文本,液位,轉彎等信息。在螺絲等上)。所需的功能是平移和縮放圖像及其ROI的能力,以及在圖像縮放到大于查看區域時滾動的能力。ROI的StrokeThickness和FontSize需要保持原始比例,但是ROI中形狀的寬度和高度需要與圖像成比例(這對于捕獲確切的像素位置以傳輸到相機至關重要)。除了滾動和其他一些問題外,我已經完成了大部分工作。我關注的兩個領域是:當我介紹ScrollViewer時,我沒有任何滾動行為。據我了解,我需要引入LayoutTransform以獲得正確的ScrollViewer行為。但是,當我這樣做時,其他區域就會開始崩潰(例如,ROI在圖像上的位置不正確,或者在平移時鼠標指針或圖像的左上角開始向遠離圖像上所選點的方向爬行。彈到MouseDown上的當前鼠標位置。)我無法完全按照我需要的方式來擴展投資回報率。我有這個工作,但這不是理想的。我沒有保留確切的筆觸粗細,也沒有考慮忽略文本塊上的比例。希望您能在代碼示例中看到我在做什么。我確信我的問題與我對Transforms及其與WPF布局系統的關系缺乏了解有關。希望呈現出我到目前為止已完成的代碼的翻譯將有所幫助(請參見下文)。僅供參考,如果有裝飾者的建議,這可能對我不起作用,因為最終我得到的裝飾者可能會多于所支持的(傳聞144個裝飾者是當事情開始崩潰的時候)。首先,下面是屏幕截圖,顯示的圖像具有ROI(文本和形狀)。矩形,橢圓形和文本需要按比例縮放和旋轉以跟隨圖像上的區域,但是它們不應該按寬度或字體大小按比例縮放。該屏幕截圖顯示了具有ROI的樣本圖像這是顯示以上圖像的XAML,以及用于縮放的Slider(稍后會進行鼠標輪縮放)<Window x:Class="PanZoomStackOverflow.MainWindow"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    mc:Ignorable="d"    Title="MainWindow" Height="768" Width="1024"><DockPanel>  <Slider x:Name="_ImageZoomSlider" DockPanel.Dock="Bottom"          Value="2"          HorizontalAlignment="Center" Margin="6,0,0,0"           Width="143" Minimum=".5" Maximum="20" SmallChange=".1"           LargeChange=".2" TickFrequency="2"           TickPlacement="BottomRight" Padding="0" Height="23"/>  <!-- This resides in a user control in my solution -->  <Grid x:Name="LayoutRoot">    <ScrollViewer Name="border" HorizontalScrollBarVisibility="Auto"                   VerticalScrollBarVisibility="Auto">      <Grid x:Name="_ImageDisplayGrid">        <Image x:Name="_DisplayImage" Margin="2" Stretch="None"   這是管理平移和縮放的C#。該代碼應該在.NET 4.0或4.5項目和解決方案中工作,假定沒有剪切/粘貼錯誤。有什么想法嗎?歡迎提出建議。
查看完整描述

3 回答

?
夢里花落0921

TA貢獻1772條經驗 獲得超6個贊

為了在不更改筆觸粗細的情況下變換形狀,可以使用Path具有變換后幾何形狀的對象。


以下XAML在畫布上放置一個Image和兩個路徑。圖像通過RenderTransform縮放和轉換。相同的變換也用于Transform兩個路徑的幾何屬性。


<Canvas>

    <Image Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg">

        <Image.RenderTransform>

            <TransformGroup x:Name="transform">

                <ScaleTransform ScaleX="0.5" ScaleY="0.5"/>

                <TranslateTransform X="100" Y="50"/>

            </TransformGroup>

        </Image.RenderTransform>

    </Image>

    <Path Stroke="Orange" StrokeThickness="2">

        <Path.Data>

            <RectangleGeometry Rect="50,100,100,50"

                               Transform="{Binding ElementName=transform}"/>

        </Path.Data>

    </Path>

    <Path Stroke="Orange" StrokeThickness="2">

        <Path.Data>

            <EllipseGeometry Center="250,100" RadiusX="50" RadiusY="50"

                             Transform="{Binding ElementName=transform}"/>

        </Path.Data>

    </Path>

</Canvas>

您的應用程序現在可以簡單地更改transform對象以響應MouseMove或MouseWheel之類的輸入事件。


當還要轉換TextBlocks或其他不應該縮放但只能移動到適當位置的元素時,事情會變得有些棘手。


您可以創建一個專門的面板,該面板可以將這種轉換應用于其子元素。這樣的面板將定義一個控制子元素位置的附加屬性,并將變換應用于該位置而不是子元素RenderTransform或LayoutTransform的位置。


這可以使您了解如何實施這樣的小組:


public class TransformPanel : Panel

{

    public static readonly DependencyProperty TransformProperty =

        DependencyProperty.Register(

            "Transform", typeof(Transform), typeof(TransformPanel),

            new FrameworkPropertyMetadata(Transform.Identity,

                FrameworkPropertyMetadataOptions.AffectsArrange));


    public static readonly DependencyProperty PositionProperty =

        DependencyProperty.RegisterAttached(

            "Position", typeof(Point?), typeof(TransformPanel),

            new PropertyMetadata(PositionPropertyChanged));


    public Transform Transform

    {

        get { return (Transform)GetValue(TransformProperty); }

        set { SetValue(TransformProperty, value); }

    }


    public static Point? GetPosition(UIElement element)

    {

        return (Point?)element.GetValue(PositionProperty);

    }


    public static void SetPosition(UIElement element, Point? value)

    {

        element.SetValue(PositionProperty, value);

    }


    protected override Size MeasureOverride(Size availableSize)

    {

        var infiniteSize = new Size(double.PositiveInfinity,

                                    double.PositiveInfinity);


        foreach (UIElement element in InternalChildren)

        {

            element.Measure(infiniteSize);

        }


        return new Size();

    }


    protected override Size ArrangeOverride(Size finalSize)

    {

        foreach (UIElement element in InternalChildren)

        {

            ArrangeElement(element, GetPosition(element));

        }


        return finalSize;

    }


    private void ArrangeElement(UIElement element, Point? position)

    {

        var arrangeRect = new Rect(element.DesiredSize);


        if (position.HasValue && Transform != null)

        {

            arrangeRect.Location = Transform.Transform(position.Value);

        }


        element.Arrange(arrangeRect);

    }


    private static void PositionPropertyChanged(

        DependencyObject obj, DependencyPropertyChangedEventArgs e)

    {

        var element = (UIElement)obj;

        var panel = VisualTreeHelper.GetParent(element) as TransformPanel;


        if (panel != null)

        {

            panel.ArrangeElement(element, (Point?)e.NewValue);

        }

    }

}

它將在XAML中像這樣使用:


<local:TransformPanel>

    <local:TransformPanel.Transform>

        <TransformGroup>

            <ScaleTransform ScaleX="0.5" ScaleY="0.5" x:Name="scale"/>

            <TranslateTransform X="100"/>

        </TransformGroup>

    </local:TransformPanel.Transform>

    <Image Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"

           RenderTransform="{Binding Transform, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TransformPanel}}"/>

    <Path Stroke="Orange" StrokeThickness="2">

        <Path.Data>

            <RectangleGeometry Rect="50,100,100,50"

                               Transform="{Binding Transform, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TransformPanel}}"/>

        </Path.Data>

    </Path>

    <Path Stroke="Orange" StrokeThickness="2">

        <Path.Data>

            <EllipseGeometry Center="250,100" RadiusX="50" RadiusY="50"

                             Transform="{Binding Transform, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TransformPanel}}"/>

        </Path.Data>

    </Path>

    <TextBlock Text="Rectangle" local:TransformPanel.Position="50,150"/>

    <TextBlock Text="Ellipse" local:TransformPanel.Position="200,150"/>

</local:TransformPanel>


查看完整回答
反對 回復 2019-11-30
?
子衿沉夜

TA貢獻1828條經驗 獲得超3個贊

可以選擇將哪些變換應用于哪些元素嗎?有沒有一種方法可以有選擇地應用,或者忽略該變換。除了Path厚度和文本不縮放外,我需要所有圖層都像一幅圖像一樣工作,另外我還需要能夠Path在圖像上移動,調整大小,旋轉并選擇每個圖層。今天我已經完成所有這些工作。是我的滾動查看器和筆觸粗細。我將嘗試您的自定義Panel想法,看看是否有什么突出之處并報告。

查看完整回答
反對 回復 2019-11-30
  • 3 回答
  • 0 關注
  • 2424 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號