WPF:由于BitmapImage仍然是未裁剪的图像,因此对CroppedBitmap的图像控制转换问题?

问题描述

我正在尝试使用BitmapImage类在WPF应用程序StageWindow.Stage中裁剪CroppedBitmap

将新裁剪的图像保存到文件JpegBitmapEncoder时,我可以看到正确裁剪的图像。 CroppedBitmap Crop

但是我实际上想将裁剪后的图像保存到List\<BitmapImage\>中,以便以后在另一个WPF图像控件中使用。该列表已经包含BitmapImages,因此将其更改为CroppedBitmaps是不够的。

为了能够存储新的croppedBitmap,我使用了类似的方法

    BitmapImage xx = CroppedBitmap1 as BitmapImage;

在将WPF图像控件设置为new BitmapImage ExpectedCroppedImage )时,它仍然显示CroppedBitmaps原始源图像而没有裁剪。

我怀疑上面的代码从新的BitmapImage删除了裁剪属性,因为BitmapImage本身没有裁剪区域的属性。但是如何只将裁剪的部分保存到新的BitmapImage中呢?

我一直在搜索,但是似乎CroppedBitmap应该可以解决我只是不知道如何以正确方式将其转换回去的窍门。

以下是澄清代码

    //Stage is the WPF image element that im reading the source image from.
    
    ImageSource StageWindowImageSource = StageWindow.Stage.source;
    CroppedBitmap Crop = new CroppedBitmap((BitmapSource)StageWindowImageSource,new Int32Rect(0,50,50));
        
    ExpectedCroppedImage = Crop.source as BitmapImage;
                            
    JpegBitmapEncoder jpg = new JpegBitmapEncoder();
    jpg.Frames.Add(BitmapFrame.Create(Crop));
    FileStream fp = new FileStream("F:/Crop.jpg",FileMode.Create,FileAccess.Write);
    jpg.Save(fp);
    fp.Close();

解决方法

ExpectedCroppedImage = Crop.Source as BitmapImage;

不返回裁剪后的位图,而是返回进行裁剪的原始位图,即Source位图。

除此之外,您不需要从CroppedBitmapBitmapImage的任何转换。

相反,请使用BitmapImage和CroppedBitmap的基类作为List的元素类型,即,将List<BitmapSource>List<ImageSource>用于您的集合。

现在,您可以分配从元素类型派生的任何类的实例。

List<BitmapSource> images = ...

CroppedBitmap croppedImage = new CroppedBitmap(...); 
images.Add(croppedImage);

BitmapImage someOtherImage = new BitmapImage(...); 
images.Add(someOtherImage);
,
private void MyMethod()
{
    ImageSource   StageWindowImageSource = img.Source;
    CroppedBitmap Crop                   = new CroppedBitmap((BitmapSource) StageWindowImageSource,new Int32Rect(20,20,150,110));

    img2.Source = GetImage(Crop,new JpegBitmapEncoder());
}

private BitmapImage GetImage(BitmapSource source,BitmapEncoder encoder)
{
    var image = new BitmapImage();

    using (var sourceMs = new MemoryStream())
    {
        encoder.Frames.Add(BitmapFrame.Create(source));
        encoder.Save(sourceMs);

        sourceMs.Position = 0;
        using (var destMs = new MemoryStream(sourceMs.ToArray()))
        {
            image.BeginInit();
            image.StreamSource = destMs;
            image.CacheOption  = BitmapCacheOption.OnLoad;
            image.EndInit();
            image.Freeze();
        }
    }

    return image;
}