首页 文章

WPF将画布中的矩形转换为图像中的选择

提问于
浏览
0

我在画布上有一个矩形,用户可以调整大小,移动等等以进行选择 . 我还有一个画布背后屏幕大小的图像(基本上是截图) .

我想将画布中的选择(矩形)转换为图像中的1:1选择(我希望图像直接位于矩形后面),因为我有矩形的Canvas.Top,Canvas.Left,Width,Height .

<Grid Name="MainGrid" SnapsToDevicePixels="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <Image x:Name="MainImage" Stretch="None" RenderOptions.BitmapScalingMode="HighQuality"/>
    <Border Background="Black" Opacity="0.4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    <Canvas Name="MainCanvas" Width="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}}" Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}}" Background="Transparent">
        <ContentControl Name="SelectionRect" />
        </ContentControl>
    </Canvas>
</Grid>

我试过这样做:( MainImage是画布下的图像)

Rect rect = new Rect(Canvas.GetLeft(SelectionRect), Canvas.GetTop(SelectionRect), SelectionRect.Width, SelectionRect.Height);
Rect from_rect = SelectionRect.TransformToVisual(this).TransformBounds(rect);

BitmapSource cropped_bitmap = new CroppedBitmap(MainImage.Source as BitmapSource, 
            new Int32Rect((int)from_rect.X, (int)from_rect.Y, (int)from_rect.Width, (int)from_rect.Height));
SelectionRectImageSource = cropped_bitmap;

但是我得到的图像(SelectionRectImageSource)是选择矩形后面的实际像素的移动版本 . 所以基本上,我不明白这些转换是如何工作的,以及我应该如何使用它们 .

示例:
Example

非常感谢!的Dolev .

1 回答

  • 1

    看起来你需要纠正图像(通常是72dpi)和演示源(通常是96dpi)之间的DPI差异 . 此外,您的第一个 Rect 不应该被 Canvas.LeftCanvas.Top 偏移; TransformToVisual 将为您处理相对偏移 .

    var source = (BitmapSource)MainImage.Source;
    
    var selectionRect = new Rect(SelectionRect.RenderSize);
    
    var sourceRect = SelectionRect.TransformToVisual(MainImage)
                                  .TransformBounds(selectionRect);
    
    var xMultiplier = source.PixelWidth / MainImage.ActualWidth;
    var yMultiplier = source.PixelHeight / MainImage.ActualHeight;
    
    sourceRect.Scale(xMultiplier, yMultiplier);
    
    var croppedBitmap = new CroppedBitmap(
        source,
        new Int32Rect(
            (int)sourceRect.X,
            (int)sourceRect.Y,
            (int)sourceRect.Width,
            (int)sourceRect.Height));
    
    SelectionRectImageSource= croppedBitmap;
    

    根据此代码所在的位置,您可能还需要将选择矩形转换为 MainImage 而不是 this (正如我所做的那样) .

    此外,如果 MainImage.Source 小于实际的 MainImage 控件,则应该分别将 MainImage 的水平和垂直对齐设置为 LeftTop ,减去已翻译的矩形,最终超出源图像的边界 . 您还需要将选择矩形钳位到 MainImage 的尺寸 .

相关问题