| File: System\Windows\Media\Imaging\CroppedBitmap.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using MS.Internal; using MS.Win32.PresentationCore; namespace System.Windows.Media.Imaging { #region CroppedBitmap /// <summary> /// CroppedBitmap provides caching functionality for a BitmapSource. /// </summary> public sealed partial class CroppedBitmap : Imaging.BitmapSource, ISupportInitialize { /// <summary> /// Constructor /// </summary> public CroppedBitmap() : base(true) { } /// <summary> /// Construct a CroppedBitmap /// </summary> /// <param name="source">BitmapSource to apply to the crop to</param> /// <param name="sourceRect">Source rect of the bitmap to use</param> public CroppedBitmap(BitmapSource source, Int32Rect sourceRect) : base(true) // Use base class virtuals { ArgumentNullException.ThrowIfNull(source); _bitmapInit.BeginInit(); Source = source; SourceRect = sourceRect; _bitmapInit.EndInit(); FinalizeCreation(); } // ISupportInitialize /// <summary> /// Prepare the bitmap to accept initialize paramters. /// </summary> public void BeginInit() { WritePreamble(); _bitmapInit.BeginInit(); } /// <summary> /// Prepare the bitmap to accept initialize paramters. /// </summary> public void EndInit() { WritePreamble(); _bitmapInit.EndInit(); IsValidForFinalizeCreation(throwIfInvalid: true); FinalizeCreation(); } private void ClonePrequel(CroppedBitmap otherCroppedBitmap) { BeginInit(); } private void ClonePostscript(CroppedBitmap otherCroppedBitmap) { EndInit(); } /// /// Create the unmanaged resources /// internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicClipper = null; Int32Rect rect = SourceRect; BitmapSource source = Source; if (rect.IsEmpty) { rect.Width = source.PixelWidth; rect.Height = source.PixelHeight; } using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapClipper( wicFactory, out wicClipper)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapClipper.Initialize( wicClipper, source.WicSourceHandle, ref rect)); } // // This is just a link in a BitmapSource chain. The memory is being used by // the BitmapSource at the end of the chain, so no memory pressure needs // to be added here. // WicSourceHandle = wicClipper; _isSourceCached = source.IsSourceCached; wicClipper = null; } catch { _bitmapInit.Reset(); throw; } finally { wicClipper?.Close(); } } CreationCompleted = true; UpdateCachedSettings(); } /// <summary> /// Notification on source changing. /// </summary> private void SourcePropertyChangedHook(DependencyPropertyChangedEventArgs e) { if (!e.IsASubPropertyChange) { BitmapSource newSource = e.NewValue as BitmapSource; _source = newSource; RegisterDownloadEventSource(_source); _syncObject = (newSource != null) ? newSource.SyncObject : _bitmapInit; } } internal override bool IsValidForFinalizeCreation(bool throwIfInvalid) { if (Source == null) { if (throwIfInvalid) { throw new InvalidOperationException(SR.Format(SR.Image_NoArgument, "Source")); } return false; } return true; } /// <summary> /// Notification on source rect changing. /// </summary> private void SourceRectPropertyChangedHook(DependencyPropertyChangedEventArgs e) { if (!e.IsASubPropertyChange) { _sourceRect = (Int32Rect)e.NewValue; } } /// <summary> /// Coerce Source /// </summary> private static object CoerceSource(DependencyObject d, object value) { CroppedBitmap bitmap = (CroppedBitmap)d; if (!bitmap._bitmapInit.IsInInit) { return bitmap._source; } else { return value; } } /// <summary> /// Coerce SourceRect /// </summary> private static object CoerceSourceRect(DependencyObject d, object value) { CroppedBitmap bitmap = (CroppedBitmap)d; if (!bitmap._bitmapInit.IsInInit) { return bitmap._sourceRect; } else { return value; } } #region Data members private BitmapSource _source; private Int32Rect _sourceRect; #endregion } #endregion // CroppedBitmap }