UWP: получение точного положения мыши (указателя) при щелчке внутри изображения - PullRequest
0 голосов
/ 14 июля 2020

У меня есть ContentDialog, где у меня есть изображение и другое изображение, наложенное на него, чтобы разместить на нем водяной знак:

    <StackPanel Orientation="Vertical">
        <Grid>
            <Image x:Name="ImageOriginal" Source="{x:Bind OriginalImage, Mode=OneWay}" MinHeight="120" MinWidth="160"/>
            <Image x:Name="ImageOverlay" Source="{x:Bind OverlayImage, Mode=OneWay}" MinHeight="120" MinWidth="160" PointerPressed="ImageOverlay_PointerPressed" />
        </Grid>
        ...

Итак, цель состояла в том, чтобы разместить текст (с центрированием по горизонтали и вертикали) на выбранном позиция.

        private void ImageOverlay_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
        {
            e.Handled = true;

            var point = e.GetCurrentPoint(ImageOverlay);
            var pointPosition = new Windows.Foundation.Point((int)point.Position.X, (int)point.Position.Y);
            Position = new PointF((float)pointPosition.X, (float)pointPosition.Y);

            UpdateOverlayImage();
        }

(PointF) - это плавающая точка ImageSharp. В приведенном выше коде мое размещение текста всегда немного отклонено, например, 50 пикселей в каждом направлении.

Я также пробовал это с помощью следующего кода, но это просто приводит к неправильному размещению текста в противоположном направлении:

            GeneralTransform transform = ImageOverlay.TransformToVisual(Window.Current.Content);
            Windows.Foundation.Point coordinatePointToWindow = transform.TransformPoint(pointPosition);

Обновление:

Кто-то хотел знать, как я рисую текст, вот он, этот код внутри UpdateOverlayImage():

        var watermarkedImage = OverlayImageBase.Clone(ctx => ctx.ApplyWatermark(font, tbWatermarkText.Text, color, Position));
        OverlayImage = watermarkedImage.ToBitmap();

А метод расширения ApplyWatermark выглядит так:

        public static IImageProcessingContext ApplyWatermark(this IImageProcessingContext processingContext,
            Font font,
            string text,
            Color color,
            PointF position)
        {
            var textGraphicOptions = new TextGraphicsOptions(true)
            {
                ColorBlendingMode = SixLabors.ImageSharp.PixelFormats.PixelColorBlendingMode.Normal,
                HorizontalAlignment = SixLabors.Fonts.HorizontalAlignment.Center,
                VerticalAlignment = SixLabors.Fonts.VerticalAlignment.Center,
            };
            return processingContext.DrawText(textGraphicOptions, text, font, color, position);
        }

Есть идеи, почему мои координаты отключены?

1 Ответ

0 голосов
/ 15 июля 2020

Я выяснил, в чем дело. Поскольку отображаемое изображение внутри ContentDialog масштабируется, координаты нарисованного текста не могут быть непосредственно теми же координатами, что и полученные из события нажатия указателя (конечно).

Поэтому мы должны вычислить относительное значение размера масштабирования. Вот как я мог это решить:

        private void ImageOverlay_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
        {
            e.Handled = true;

            PointerPoint ptrPt = e.GetCurrentPoint(ImageOverlay);

            // As the image is scaled we have to caluclate the position inside the image based on the position of the pointer pressed
            float imagePressedX = (float)(OriginalImage.PixelWidth / ImageOverlay.ActualWidth * ptrPt.Position.X);
            float imagePressedY = (float)(OriginalImage.PixelHeight / ImageOverlay.ActualHeight * ptrPt.Position.Y); ;
            Position = new PointF(imagePressedX, imagePressedY);

            UpdateOverlayImage();
        }
...