代码之家  ›  专栏  ›  技术社区  ›  StezPet

在WinRT中裁剪/剪辑图像[已关闭]

  •  1
  • StezPet  · 技术社区  · 10 年前

    如何在WinRT中裁剪/剪辑图像。我有一个完全填充在windows 8窗口中的图像。我需要从中心剪辑/裁剪图像,我需要将两个图像部分显示为两个单独的网格。我怎样才能通过窗口8做到这一点。是否可以在不使用WritableBitmapEx的情况下实现这一点。如果没有,如何通过WritableBitmapEx执行相同操作。

    3 回复  |  直到 10 年前
        1
  •  2
  •   Filip Skakun    10 年前

    实际上,有很多方法可以做到这一点,每个方法都有利弊。

    • WriteableBitmapEx 似乎是一个流行的解决方案。我在 WinRT XAML Toolkit 这两者基本上都是从完整图像位图复制像素块。这可能不是最快的方法,但如果你想得到一个开箱即用的解决方案,这是一个容易使用的方法。您需要复制像素,因此在操作时没有优化内存使用,因此可能会更快地耗尽超大图像的内存。如果需要,您可以轻松地重新搜索,但最终将结果保存到图像文件中。
    • 这个 BitmapDecoder Jan推荐的解决方案是我经常使用的解决方案,因为它是平台的一部分,用本地代码编写,可能经过了高度优化,您不会复制像素,但如果您想重新操作,则需要再次解码图像。
    • Xyroid的建议 Clip 几何图形是一种仅快速显示的解决方案。实际上,您并没有修改内存中的位图,只是在屏幕上显示位图的一个区域。然后,您需要将整个图像保存在内存中,如果您想保存它,您仍然需要更新位图以保存它,可以使用前两种解决方案之一,也可以使用 RenderTargetBitmap.Render() 如果屏幕分辨率足够您使用。不过,更新屏幕上显示的裁剪区域以进行快速预览应该很快。
    • 另一个是 Rectangle 填充了 ImageBrush 在那里你可以申请 Transform 并指定 长方形 大小以控制裁剪。它与 夹子 解决方案,而不是剪切图像,在这种情况下,您实际上必须使用 Tramsform (您也可以在 夹子 - RectangleGeometry ). 用于快速更新-使用 使改变 实际上可能比更新几何体快一点,并且还支持缩放和旋转。
        2
  •  1
  •   Jan Hommes    10 年前

    您可以使用Bitmapdecoder和BitmapTransform类。 This example 非常适合种植。你还应该阅读 this tutorial 用于剪辑。基本上,您实现了如下函数(取自示例):

    async public static Task<ImageSource> GetCroppedBitmapAsync(StorageFile originalImgFile, Point startPoint, Size corpSize, double scale) 
    { 
    
    
    if (double.IsNaN(scale) || double.IsInfinity(scale)) 
    { 
        scale = 1; 
    } 
    
    
    // Convert start point and size to integer. 
    uint startPointX = (uint)Math.Floor(startPoint.X * scale); 
    uint startPointY = (uint)Math.Floor(startPoint.Y * scale); 
    uint height = (uint)Math.Floor(corpSize.Height * scale); 
    uint width = (uint)Math.Floor(corpSize.Width * scale); 
    
    
    using (IRandomAccessStream stream = await originalImgFile.OpenReadAsync()) 
    { 
    
    
        // Create a decoder from the stream. With the decoder, we can get  
        // the properties of the image. 
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 
    
        // The scaledSize of original image. 
        uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale); 
        uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale); 
    
    
    
        // Refine the start point and the size.  
        if (startPointX + width > scaledWidth) 
        { 
            startPointX = scaledWidth - width; 
        } 
    
    
        if (startPointY + height > scaledHeight) 
        { 
            startPointY = scaledHeight - height; 
        } 
    
    
        // Create cropping BitmapTransform and define the bounds. 
        BitmapTransform transform = new BitmapTransform(); 
        BitmapBounds bounds = new BitmapBounds(); 
        bounds.X = startPointX; 
        bounds.Y = startPointY; 
        bounds.Height = height; 
        bounds.Width = width; 
        transform.Bounds = bounds; 
    
    
        transform.ScaledWidth = scaledWidth; 
        transform.ScaledHeight = scaledHeight; 
    
        // Get the cropped pixels within the bounds of transform. 
        PixelDataProvider pix = await decoder.GetPixelDataAsync( 
            BitmapPixelFormat.Bgra8, 
            BitmapAlphaMode.Straight, 
            transform, 
            ExifOrientationMode.IgnoreExifOrientation, 
            ColorManagementMode.ColorManageToSRgb); 
        byte[] pixels = pix.DetachPixelData(); 
    
    
        // Stream the bytes into a WriteableBitmap 
        WriteableBitmap cropBmp = new WriteableBitmap((int)width, (int)height); 
        Stream pixStream = cropBmp.PixelBuffer.AsStream(); 
        pixStream.Write(pixels, 0, (int)(width * height * 4)); 
    
    
        return cropBmp; 
    } 
    
    
    } 
    
        3
  •  1
  •   Community T.Woody    7 年前

    XAML静态方式,如果我的屏幕大小为1366x768&我想剪辑中心400x300的图像,然后我会这样做。

    <Image Source="Assets/img100.png" Stretch="Fill">
        <Image.Clip>
            <RectangleGeometry Rect="483,234,400,300" />
        </Image.Clip>
    </Image>
    

    动态方式。它将对所有分辨率进行中心剪裁,尽管高度和分辨率都是一样的;宽度是固定的。

    double _Height = 300, _Width = 400;
    img.Clip = new RectangleGeometry 
    {
        Rect = new Rect((Window.Current.Bounds.Width - _Width) / 2, (Window.Current.Bounds.Height - _Height) / 2, _Width, _Height)
    };
    

    别忘了结账。。。

    How to resize Image in C# WinRT/winmd?

    Crop image with rectangle

    Crop image with dynamic rectangle coordinate

    Cropping tool after file picker (like the one after you take a picture)

    推荐文章