2014-11-20 43 views
0

我在画布上有一个矩形,用户可以调整大小,移动等来进行选择。 我也有一个图像背后的画布大小(基本上是一个截图)。WPF将矩形在画布中转换为图像中的选择

我想将画布中的选择(矩形)转换为图像中的1:1选择(我希望图像直接在矩形后面)给定矩形的Canvas.Top,Canvas.Left ,宽度,高度。

<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

看起来您需要更正图像(通常为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的尺寸。

+0

谢谢,这个工程,但只有在Windows的设置下,100%的dpi缩放。 显然,我在Windows中将dpi缩放到125%的事实使您的代码无法正常工作。你知道我能做些什么吗? 另外我会花一些时间来了解你做了什么。 – dlv 2014-11-20 18:16:15

+0

我简化了一些计算,修改后的版本似乎对我来说产生了更好的结果。 – 2014-11-20 18:19:11

+0

非常感谢!即使使用我的电脑的DPI缩放,这也可以工作。 – dlv 2014-11-20 18:40:54