WPF 图像裁剪

Posted

技术标签:

【中文标题】WPF 图像裁剪【英文标题】:WPF Image Cropping 【发布时间】:2016-08-19 20:10:17 【问题描述】:

我遇到了图像裁剪问题。当我尝试用矩形裁剪图像时,裁剪区域设置为一些奇怪的值。 这是xaml代码:

   <Grid Name="GridImage">
        <Image Name="LoadedImage" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality">
        </Image>
        <Canvas  x:Name="ImageCanvas" ClipToBounds="True">
            <Rectangle x:Name="SelectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
        </Canvas>
  </Grid>

这里是我如何裁剪图像:

            var imagePosition = LoadedImage.TransformToAncestor(GridImage).Transform(new Point(0, 0));
            Rect rect1 = new Rect(Math.Max(Canvas.GetLeft(SelectionRectangle) - imagePosition.X, 0), Math.Max(Canvas.GetTop(SelectionRectangle) - imagePosition.Y, 0), SelectionRectangle.Width, SelectionRectangle.Height);
            var ratioX = LoadedImage.Source.Width / LoadedImage.ActualWidth;
            var ratioY = LoadedImage.Source.Height / LoadedImage.ActualHeight;


            Int32Rect rcFrom = new Int32Rect
            
                X = (int)(rect1.X * ratioX),
                Y = (int)(rect1.Y * ratioY),
                Width = (int)(rect1.Width * ratioX),
                Height = (int)(rect1.Height * ratioY)
            ;
            try
            
                BitmapSource bs = new CroppedBitmap((BitmapSource)LoadedImage.Source, rcFrom);
                LoadedImage.Source = bs;
                SetImageStretch(LoadedImage);
                SetElementVisibility(Visibility.Hidden, Visibility.Visible, SelectionRectangle);
            


    private void SetImageStretch(Image image)
    
        if (image.Source.Width > image.ActualWidth || image.Source.Height > image.ActualHeight)
            image.Stretch = Stretch.Uniform;
        else image.Stretch = Stretch.None;
    

有人知道如何解决吗?

裁剪前的样子:

裁剪后的样子:

【问题讨论】:

如果没有一个好的minimal reproducible example 可以可靠地重现您的问题,就不可能确定您需要什么答案。最有可能的是,您根本不应该创建新的位图,而应该依赖 Image 元素的转换选项来简单地限制原始位图在屏幕上的显示方式。请提供一个好的 MCVE 并准确地解释该代码现在做什么以及您希望它做什么。 【参考方案1】:

问题很可能出在图像分辨率上,例如300 dpi,与屏幕分辨率(很可能是 96 dpi)相比。你检查过图片的 PixelWidth 和 PixelHeight 吗?

【讨论】:

我的 PixelWidth = 1920, PixelHeight = 1080, dpiX = 72, dpiY = 72 并且 PixelFormat 是 BGR32。但是为什么使用 ratioX 和 ratioY 不能正确裁剪呢? 我需要将图像转换为屏幕分辨率还是有其他解决方案?附言我的应用程序应该处理数千张图像并将每个图像转换为屏幕分辨率将是非常慢的解决方案 谢谢。它有帮助。 @Anton 您不需要转换图像,只需考虑不同的屏幕和图像 DPI 重新计算裁剪矩形坐标。

以上是关于WPF 图像裁剪的主要内容,如果未能解决你的问题,请参考以下文章

从 WPF 中的图像裁剪对角线区域

wpf CroppedBitmap 将图像裁剪为双精度像素值

WPF IrfanView 风格的图像裁剪控件

WPF 裁剪问题

WPF 图像集边界

没有 .net 库的图像裁剪 C#