Пример #1
0
 public CroppedBitmap GetBitMap(int id)
 {
     var p = GetPosition(id);
     var bitmap = new CroppedBitmap();
     bitmap.BeginInit();
     bitmap.Source = _imageSource;
     bitmap.SourceRect = new Int32Rect(p.X * _cropSize, p.Y * _cropSize, _cropSize, _cropSize);
     bitmap.EndInit();
     return bitmap;
 }
Пример #2
0
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                CroppedBitmap cb = new CroppedBitmap();
                cb.BeginInit();
                cb.Source = (BitmapSource)value;

                cb.SourceRect = new Int32Rect(int.Parse(parameter.ToString()), 0, 256, 256);
                cb.EndInit();
                return new ImageBrush((ImageSource)cb);
                //return (ImageSource)cb;
            }
Пример #3
0
        internal override void FinalizeCreation() 
        {
            _bitmapInit.EnsureInitializedComplete(); 
            Uri uri = UriSource; 
            if (_baseUri != null)
                uri = new Uri(_baseUri, UriSource); 

            if ((CreateOptions & BitmapCreateOptions.IgnoreImageCache) != 0)
            {
                ImagingCache.RemoveFromImageCache(uri); 
            }
 
            BitmapImage bitmapImage = CheckCache(uri); 

            if (bitmapImage != null && 
                bitmapImage.CheckAccess() &&
                bitmapImage.SourceRect.Equals(SourceRect) &&
                bitmapImage.DecodePixelWidth == DecodePixelWidth &&
                bitmapImage.DecodePixelHeight == DecodePixelHeight && 
                bitmapImage.Rotation == Rotation &&
                (bitmapImage.CreateOptions & BitmapCreateOptions.IgnoreColorProfile) == 
                (CreateOptions & BitmapCreateOptions.IgnoreColorProfile) 
               )
            { 
                _syncObject = bitmapImage.SyncObject;
                lock (_syncObject)
                {
                    WicSourceHandle = bitmapImage.WicSourceHandle; 
                    IsSourceCached = bitmapImage.IsSourceCached;
                    _convertedDUCEPtr = bitmapImage._convertedDUCEPtr; 
 
                    //
                    // We nee d to keep the strong reference to the cached image for a few reasons: 
                    //
                    //    The application may release the original cached image and then keep a
                    //    reference to this image only, in which case, the cache can be collected.
                    //    This will cause a few undesirable results: 
                    //    1. The application may choose to decode the same URI again in which case
                    //       we will not retrieve it from the cache even though we have a copy already 
                    //       decoded. 
                    //    2. The original cached image holds onto the file stream indirectly which if
                    //       collected can cause bad behavior if the entire image is not loaded into 
                    //       memory.
                    //
                    _cachedBitmapImage = bitmapImage;
                } 
                UpdateCachedSettings();
                return; 
            } 

            BitmapDecoder decoder = null; 
            if (_decoder == null)
            {
                // Note: We do not want to insert in the cache if there is a chance that
                //       the decode pixel width/height may cause the decoder LOD to change 
                decoder = BitmapDecoder.CreateFromUriOrStream(
                    _baseUri, 
                    UriSource, 
                    StreamSource,
                    CreateOptions & ~BitmapCreateOptions.DelayCreation, 
                    BitmapCacheOption.None, // do not cache the frames since we will do that here
                    _uriCachePolicy,
                    false
                    ); 

                if (decoder.IsDownloading) 
                { 
                    _isDownloading = true;
                    _decoder = decoder; 
                    decoder.DownloadProgress += OnDownloadProgress;
                    decoder.DownloadCompleted += OnDownloadCompleted;
                    decoder.DownloadFailed += OnDownloadFailed;
                } 
                else
                { 
                    Debug.Assert(decoder.SyncObject != null); 
                }
            } 
            else
            {
                // We already had a decoder, meaning we were downloading
                Debug.Assert(!_decoder.IsDownloading); 
                decoder = _decoder;
                _decoder = null; 
            } 

            if (decoder.Frames.Count == 0) 
            {
                throw new System.ArgumentException(SR.Get(SRID.Image_NoDecodeFrames));
            }
 
            BitmapFrame frame = decoder.Frames[0];
            BitmapSource source = frame; 
 
            Int32Rect sourceRect = SourceRect;
 
            if (sourceRect.X == 0 && sourceRect.Y == 0 &&
                sourceRect.Width == source.PixelWidth &&
                sourceRect.Height == source.PixelHeight)
            { 
                sourceRect = Int32Rect.Empty;
            } 
 
            if (!sourceRect.IsEmpty)
            { 
                CroppedBitmap croppedSource = new CroppedBitmap();
                croppedSource.BeginInit();
                croppedSource.Source = source;
                croppedSource.SourceRect = sourceRect; 
                croppedSource.EndInit();
 
                source = croppedSource; 
                if (_isDownloading)
                { 
                    // Unregister the download events because this is a dummy image. See comment below.
                    source.UnregisterDownloadEventSource();
                }
            } 

            int finalWidth = DecodePixelWidth; 
            int finalHeight = DecodePixelHeight; 

            if (finalWidth == 0 && finalHeight == 0) 
            {
                finalWidth = source.PixelWidth;
                finalHeight = source.PixelHeight;
            } 
            else if (finalWidth == 0)
            { 
                finalWidth = (source.PixelWidth * finalHeight) / source.PixelHeight; 
            }
            else if (finalHeight == 0) 
            {
                finalHeight = (source.PixelHeight * finalWidth) / source.PixelWidth;
            }
 
            if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight ||
                Rotation != Rotation.Rotate0) 
            { 
                TransformedBitmap transformedSource = new TransformedBitmap();
                transformedSource.BeginInit(); 
                transformedSource.Source = source;

                TransformGroup transformGroup = new TransformGroup();
 
                if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight)
                { 
                    int oldWidth = source.PixelWidth; 
                    int oldHeight = source.PixelHeight;
 
                    Debug.Assert(oldWidth > 0 && oldHeight > 0);

                    transformGroup.Children.Add(
                        new ScaleTransform( 
                            (1.0*finalWidth)/ oldWidth,
                            (1.0*finalHeight)/oldHeight)); 
                } 

                if (Rotation != Rotation.Rotate0) 
                {
                    double rotation = 0.0;

                    switch (Rotation) 
                    {
                        case Rotation.Rotate0: 
                            rotation = 0.0; 
                            break;
                        case Rotation.Rotate90: 
                            rotation = 90.0;
                            break;
                        case Rotation.Rotate180:
                            rotation = 180.0; 
                            break;
                        case Rotation.Rotate270: 
                            rotation = 270.0; 
                            break;
                        default: 
                            Debug.Assert(false);
                            break;
                    }
 
                    transformGroup.Children.Add(new RotateTransform(rotation));
                } 
 
                transformedSource.Transform = transformGroup;
 
                transformedSource.EndInit();

                source = transformedSource;
                if (_isDownloading) 
                {
                    // 
                    // If we're currently downloading, then the BitmapFrameDecode isn't actually 
                    // the image, it's just a 1x1 placeholder. The chain we're currently building
                    // will be replaced with another chain once download completes, so there's no 
                    // need to have this chain handle DownloadCompleted.
                    //
                    // Having this chain handle DownloadCompleted is actually a bad thing. Because
                    // the dummy is just 1x1, the TransformedBitmap we're building here will have 
                    // a large scaling factor (to scale the image from 1x1 up to whatever
                    // DecodePixelWidth/Height specifies). When the TransformedBitmap receives 
                    // DownloadCompleted from the BFD, it will call into WIC to create a new 
                    // bitmap scaler using the same large scaling factor, which can produce a huge
                    // bitmap (since the BFD is now no longer 1x1). This problem is made worse if 
                    // this BitmapImage has BitmapCacheOption.OnLoad, since that will put a
                    // CachedBitmap after the TransformedBitmap. When DownloadCompleted propagates
                    // from the TransformedBitmap down to the CachedBitmap, the CachedBitmap will
                    // call CreateBitmapFromSource using the TransformedBitmap, which calls 
                    // CopyPixels on the huge TransformedBitmap. We want to avoid chewing up the
                    // CPU and the memory, so we unregister the download event handlers here. 
                    // 
                    source.UnregisterDownloadEventSource();
                } 
            }

            //
            // If the original image has a color profile and IgnoreColorProfile is not one of the create options, 
            // apply the profile so bits are color-corrected.
            // 
            if ((CreateOptions & BitmapCreateOptions.IgnoreColorProfile) == 0 && 
                frame.ColorContexts != null &&
                frame.ColorContexts[0] != null && 
                frame.ColorContexts[0].IsValid &&
                source.Format.Format != PixelFormatEnum.Extended
                )
            { 
                // NOTE: Never do this for a non-MIL pixel format, because the format converter has
                // special knowledge to deal with the profile 
 
                PixelFormat duceFormat = BitmapSource.GetClosestDUCEFormat(source.Format, source.Palette);
                bool changeFormat = (source.Format != duceFormat); 
                ColorContext destinationColorContext;

                // We need to make sure, we can actually create the ColorContext for the destination duceFormat
                // If the duceFormat is gray or scRGB, the following is not supported, so we cannot 
                // create the ColorConvertedBitmap
                try 
                { 
                    destinationColorContext= new ColorContext(duceFormat);
                } 
                catch (NotSupportedException)
                {
                    destinationColorContext = null;
                } 

                if (destinationColorContext != null) 
                { 
                    bool conversionSuccess = false;
                    bool badColorContext = false; 

                    // First try if the color converter can handle the source format directly
                    // Its possible that the color converter does not support certain pixelformats, so put a try/catch here.
                    try 
                    {
                        ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap( 
                            source, 
                            frame.ColorContexts[0],
                            destinationColorContext, 
                            duceFormat
                            );

                        source = colorConvertedBitmap; 
                        if (_isDownloading)
                        { 
                            // Unregister the download events because this is a dummy image. See comment above. 
                            source.UnregisterDownloadEventSource();
                        } 
                        conversionSuccess = true;
                    }
                    catch (NotSupportedException)
                    { 
                    }
                    catch (FileFormatException) 
                    { 
                        // If the file contains a bad color context, we catch the exception here
                        // and don't bother trying the color conversion below, since color transform isn't possible 
                        // with the given color context.
                        badColorContext = true;
                    }
 
                    if (!conversionSuccess && !badColorContext && changeFormat)
                    {   // If the conversion failed, we first use 
                        // a FormatConvertedBitmap, and then Color Convert that one... 
                        FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap(source, duceFormat, source.Palette, 0.0);
 
                        ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap(
                            formatConvertedBitmap,
                            frame.ColorContexts[0],
                            destinationColorContext, 
                            duceFormat
                            ); 
 
                        source = colorConvertedBitmap;
                        if (_isDownloading) 
                        {
                            // Unregister the download events because this is a dummy image. See comment above.
                            source.UnregisterDownloadEventSource();
                        } 
                    }
                } 
            } 

            if (CacheOption != BitmapCacheOption.None) 
            {
                try
                {
                    // The bitmaps bits could be corrupt, and this will cause an exception if the CachedBitmap forces a decode. 
                    CachedBitmap cachedSource = new CachedBitmap(source, CreateOptions & ~BitmapCreateOptions.DelayCreation, CacheOption);
                    source = cachedSource; 
                    if (_isDownloading) 
                    {
                        // Unregister the download events because this is a dummy image. See comment above. 
                        source.UnregisterDownloadEventSource();
                    }
                }
                catch (Exception e) 
                {
                    RecoverFromDecodeFailure(e); 
                    CreationCompleted = true; // we're bailing out because the decode failed 
                    return;
                } 
            }

            // If CacheOption == OnLoad, no need to keep the stream around
            if (decoder != null && CacheOption == BitmapCacheOption.OnLoad) 
            {
                decoder.CloseStream(); 
            } 
            else if (CacheOption != BitmapCacheOption.OnLoad)
            { 
                //ensure that we don't GC the source
                _finalSource = source;
            }
 
            WicSourceHandle = source.WicSourceHandle;
            IsSourceCached = source.IsSourceCached; 
 
            CreationCompleted = true;
            UpdateCachedSettings(); 

            // Only insert in the imaging cache if download is complete
            if (!IsDownloading)
            { 
                InsertInCache(uri);
            } 
        } 
Пример #4
0
        internal override void FinalizeCreation()
        {
            _bitmapInit.EnsureInitializedComplete();
            Uri uri = UriSource;

            if (_baseUri != null)
            {
                uri = new Uri(_baseUri, UriSource);
            }

            if ((CreateOptions & BitmapCreateOptions.IgnoreImageCache) != 0)
            {
                ImagingCache.RemoveFromImageCache(uri);
            }

            BitmapImage bitmapImage = CheckCache(uri);

            if (bitmapImage != null &&
                bitmapImage.CheckAccess() &&
                bitmapImage.SourceRect.Equals(SourceRect) &&
                bitmapImage.DecodePixelWidth == DecodePixelWidth &&
                bitmapImage.DecodePixelHeight == DecodePixelHeight &&
                bitmapImage.Rotation == Rotation &&
                (bitmapImage.CreateOptions & BitmapCreateOptions.IgnoreColorProfile) ==
                (CreateOptions & BitmapCreateOptions.IgnoreColorProfile)
                )
            {
                _syncObject = bitmapImage.SyncObject;
                lock (_syncObject)
                {
                    WicSourceHandle   = bitmapImage.WicSourceHandle;
                    IsSourceCached    = bitmapImage.IsSourceCached;
                    _convertedDUCEPtr = bitmapImage._convertedDUCEPtr;

                    //
                    // We nee d to keep the strong reference to the cached image for a few reasons:
                    //
                    //    The application may release the original cached image and then keep a
                    //    reference to this image only, in which case, the cache can be collected.
                    //    This will cause a few undesirable results:
                    //    1. The application may choose to decode the same URI again in which case
                    //       we will not retrieve it from the cache even though we have a copy already
                    //       decoded.
                    //    2. The original cached image holds onto the file stream indirectly which if
                    //       collected can cause bad behavior if the entire image is not loaded into
                    //       memory.
                    //
                    _cachedBitmapImage = bitmapImage;
                }
                UpdateCachedSettings();
                return;
            }

            BitmapDecoder decoder = null;

            if (_decoder == null)
            {
                // Note: We do not want to insert in the cache if there is a chance that
                //       the decode pixel width/height may cause the decoder LOD to change
                decoder = BitmapDecoder.CreateFromUriOrStream(
                    _baseUri,
                    UriSource,
                    StreamSource,
                    CreateOptions & ~BitmapCreateOptions.DelayCreation,
                    BitmapCacheOption.None, // do not cache the frames since we will do that here
                    _uriCachePolicy,
                    false
                    );

                if (decoder.IsDownloading)
                {
                    _isDownloading             = true;
                    _decoder                   = decoder;
                    decoder.DownloadProgress  += OnDownloadProgress;
                    decoder.DownloadCompleted += OnDownloadCompleted;
                    decoder.DownloadFailed    += OnDownloadFailed;
                }
                else
                {
                    Debug.Assert(decoder.SyncObject != null);
                }
            }
            else
            {
                // We already had a decoder, meaning we were downloading
                Debug.Assert(!_decoder.IsDownloading);
                decoder  = _decoder;
                _decoder = null;
            }

            if (decoder.Frames.Count == 0)
            {
                throw new System.ArgumentException(SR.Get(SRID.Image_NoDecodeFrames));
            }

            BitmapFrame  frame  = decoder.Frames[0];
            BitmapSource source = frame;

            Int32Rect sourceRect = SourceRect;

            if (sourceRect.X == 0 && sourceRect.Y == 0 &&
                sourceRect.Width == source.PixelWidth &&
                sourceRect.Height == source.PixelHeight)
            {
                sourceRect = Int32Rect.Empty;
            }

            if (!sourceRect.IsEmpty)
            {
                CroppedBitmap croppedSource = new CroppedBitmap();
                croppedSource.BeginInit();
                croppedSource.Source     = source;
                croppedSource.SourceRect = sourceRect;
                croppedSource.EndInit();

                source = croppedSource;
                if (_isDownloading)
                {
                    // Unregister the download events because this is a dummy image. See comment below.
                    source.UnregisterDownloadEventSource();
                }
            }

            int finalWidth  = DecodePixelWidth;
            int finalHeight = DecodePixelHeight;

            if (finalWidth == 0 && finalHeight == 0)
            {
                finalWidth  = source.PixelWidth;
                finalHeight = source.PixelHeight;
            }
            else if (finalWidth == 0)
            {
                finalWidth = (source.PixelWidth * finalHeight) / source.PixelHeight;
            }
            else if (finalHeight == 0)
            {
                finalHeight = (source.PixelHeight * finalWidth) / source.PixelWidth;
            }

            if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight ||
                Rotation != Rotation.Rotate0)
            {
                TransformedBitmap transformedSource = new TransformedBitmap();
                transformedSource.BeginInit();
                transformedSource.Source = source;

                TransformGroup transformGroup = new TransformGroup();

                if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight)
                {
                    int oldWidth  = source.PixelWidth;
                    int oldHeight = source.PixelHeight;

                    Debug.Assert(oldWidth > 0 && oldHeight > 0);

                    transformGroup.Children.Add(
                        new ScaleTransform(
                            (1.0 * finalWidth) / oldWidth,
                            (1.0 * finalHeight) / oldHeight));
                }

                if (Rotation != Rotation.Rotate0)
                {
                    double rotation = 0.0;

                    switch (Rotation)
                    {
                    case Rotation.Rotate0:
                        rotation = 0.0;
                        break;

                    case Rotation.Rotate90:
                        rotation = 90.0;
                        break;

                    case Rotation.Rotate180:
                        rotation = 180.0;
                        break;

                    case Rotation.Rotate270:
                        rotation = 270.0;
                        break;

                    default:
                        Debug.Assert(false);
                        break;
                    }

                    transformGroup.Children.Add(new RotateTransform(rotation));
                }

                transformedSource.Transform = transformGroup;

                transformedSource.EndInit();

                source = transformedSource;
                if (_isDownloading)
                {
                    //
                    // If we're currently downloading, then the BitmapFrameDecode isn't actually
                    // the image, it's just a 1x1 placeholder. The chain we're currently building
                    // will be replaced with another chain once download completes, so there's no
                    // need to have this chain handle DownloadCompleted.
                    //
                    // Having this chain handle DownloadCompleted is actually a bad thing. Because
                    // the dummy is just 1x1, the TransformedBitmap we're building here will have
                    // a large scaling factor (to scale the image from 1x1 up to whatever
                    // DecodePixelWidth/Height specifies). When the TransformedBitmap receives
                    // DownloadCompleted from the BFD, it will call into WIC to create a new
                    // bitmap scaler using the same large scaling factor, which can produce a huge
                    // bitmap (since the BFD is now no longer 1x1). This problem is made worse if
                    // this BitmapImage has BitmapCacheOption.OnLoad, since that will put a
                    // CachedBitmap after the TransformedBitmap. When DownloadCompleted propagates
                    // from the TransformedBitmap down to the CachedBitmap, the CachedBitmap will
                    // call CreateBitmapFromSource using the TransformedBitmap, which calls
                    // CopyPixels on the huge TransformedBitmap. We want to avoid chewing up the
                    // CPU and the memory, so we unregister the download event handlers here.
                    //
                    source.UnregisterDownloadEventSource();
                }
            }

            //
            // If the original image has a color profile and IgnoreColorProfile is not one of the create options,
            // apply the profile so bits are color-corrected.
            //
            if ((CreateOptions & BitmapCreateOptions.IgnoreColorProfile) == 0 &&
                frame.ColorContexts != null &&
                frame.ColorContexts[0] != null &&
                frame.ColorContexts[0].IsValid &&
                source.Format.Format != PixelFormatEnum.Extended
                )
            {
                // NOTE: Never do this for a non-MIL pixel format, because the format converter has
                // special knowledge to deal with the profile

                PixelFormat  duceFormat   = BitmapSource.GetClosestDUCEFormat(source.Format, source.Palette);
                bool         changeFormat = (source.Format != duceFormat);
                ColorContext destinationColorContext;

                // We need to make sure, we can actually create the ColorContext for the destination duceFormat
                // If the duceFormat is gray or scRGB, the following is not supported, so we cannot
                // create the ColorConvertedBitmap
                try
                {
                    destinationColorContext = new ColorContext(duceFormat);
                }
                catch (NotSupportedException)
                {
                    destinationColorContext = null;
                }

                if (destinationColorContext != null)
                {
                    bool conversionSuccess = false;
                    bool badColorContext   = false;

                    // First try if the color converter can handle the source format directly
                    // Its possible that the color converter does not support certain pixelformats, so put a try/catch here.
                    try
                    {
                        ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap(
                            source,
                            frame.ColorContexts[0],
                            destinationColorContext,
                            duceFormat
                            );

                        source = colorConvertedBitmap;
                        if (_isDownloading)
                        {
                            // Unregister the download events because this is a dummy image. See comment above.
                            source.UnregisterDownloadEventSource();
                        }
                        conversionSuccess = true;
                    }
                    catch (NotSupportedException)
                    {
                    }
                    catch (FileFormatException)
                    {
                        // If the file contains a bad color context, we catch the exception here
                        // and don't bother trying the color conversion below, since color transform isn't possible
                        // with the given color context.
                        badColorContext = true;
                    }

                    if (!conversionSuccess && !badColorContext && changeFormat)
                    {   // If the conversion failed, we first use
                        // a FormatConvertedBitmap, and then Color Convert that one...
                        FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap(source, duceFormat, source.Palette, 0.0);

                        ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap(
                            formatConvertedBitmap,
                            frame.ColorContexts[0],
                            destinationColorContext,
                            duceFormat
                            );

                        source = colorConvertedBitmap;
                        if (_isDownloading)
                        {
                            // Unregister the download events because this is a dummy image. See comment above.
                            source.UnregisterDownloadEventSource();
                        }
                    }
                }
            }

            if (CacheOption != BitmapCacheOption.None)
            {
                try
                {
                    // The bitmaps bits could be corrupt, and this will cause an exception if the CachedBitmap forces a decode.
                    CachedBitmap cachedSource = new CachedBitmap(source, CreateOptions & ~BitmapCreateOptions.DelayCreation, CacheOption);
                    source = cachedSource;
                    if (_isDownloading)
                    {
                        // Unregister the download events because this is a dummy image. See comment above.
                        source.UnregisterDownloadEventSource();
                    }
                }
                catch (Exception e)
                {
                    RecoverFromDecodeFailure(e);
                    CreationCompleted = true; // we're bailing out because the decode failed
                    return;
                }
            }

            // If CacheOption == OnLoad, no need to keep the stream around
            if (decoder != null && CacheOption == BitmapCacheOption.OnLoad)
            {
                decoder.CloseStream();
            }
            else if (CacheOption != BitmapCacheOption.OnLoad)
            {
                //ensure that we don't GC the source
                _finalSource = source;
            }

            WicSourceHandle = source.WicSourceHandle;
            IsSourceCached  = source.IsSourceCached;

            CreationCompleted = true;
            UpdateCachedSettings();

            // Only insert in the imaging cache if download is complete
            if (!IsDownloading)
            {
                InsertInCache(uri);
            }
        }
Пример #5
0
        protected CroppedBitmap[] GetSpriteSources(String source, Int32 rows, Int32 columns)
        {
            var sourceImage = ImageUtility.InitializeBitmapSourceFromLocation(source);

            var sourceWidth = sourceImage.PixelWidth / columns;
            var sourceHeight = sourceImage.PixelHeight / rows;

            var sources = new CroppedBitmap[rows * columns];
            for (Int32 index = 0; index < sources.Count(); index++)
            {
                var xPosition = (index % columns) * sourceWidth;
                var yPosition = (index / columns) * sourceHeight;

                var croppedBitmap = new CroppedBitmap();
                croppedBitmap.BeginInit();
                croppedBitmap.Source = sourceImage;
                croppedBitmap.SourceRect = new Int32Rect(xPosition, yPosition, sourceWidth, sourceHeight);
                croppedBitmap.EndInit();
                sources[index] = croppedBitmap;
            }

            return sources;
        }
Пример #6
0
        /// <summary>
        /// When implemented in a derived class, returns an object that is provided as the value of
        /// the target property for this markup extension.
        /// </summary>
        /// <param name="serviceProvider">
        /// A service provider helper that can provide services for the markup extension.
        /// </param>
        /// <returns>
        /// The object value to set on the property where the extension is applied.
        /// </returns>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            // Setting BitmapImage.SourceRect has no effect. Need to use CroppedBitmap.
            if (WindowsHelper.IsInDesignMode)
            {
                // ----- Design time:
                // Design mode requires special code when used inside a WPF styles.
                var bitmapImage = Source as BitmapImage;
                if (bitmapImage == null)
                    return null;

                var croppedBitmap = new CroppedBitmap();
                croppedBitmap.BeginInit();
                croppedBitmap.Source = new BitmapImage(bitmapImage.UriSource);
                croppedBitmap.SourceRect = SourceRect;
                croppedBitmap.EndInit();
                croppedBitmap.Freeze();

                return croppedBitmap;
            }
            else
            {
                // ----- Run time:
                var bitmapSource = Source as BitmapSource;
                if (bitmapSource == null)
                    return null;

                // Freeze bitmap for performance.
                bitmapSource.Freeze();

                var croppedBitmap = new CroppedBitmap(bitmapSource, SourceRect);
                croppedBitmap.Freeze();

                return croppedBitmap;
            }
        }
        /// <summary>
        /// Get one cell from sprite sheet
        /// </summary>
        /// <param name="sSpriteSheet">Filename of sprite sheet</param>
        /// <returns>Cropped image as a new CroppedBitmap</returns>
        public CroppedBitmap GetCell(string sSpriteSheet,int iStartX,int iStartY,int iEndX,int iEndY)
        {
            Image iWhichSpriteSheet;
            dSpriteSheets.TryGetValue(sSpriteSheet, out iWhichSpriteSheet);

            CroppedBitmap cbNew = new CroppedBitmap();
            cbNew.BeginInit();
            cbNew.Source = (BitmapSource)iWhichSpriteSheet.Source;
            cbNew.SourceRect = new Int32Rect(iStartX,iStartY,iEndX,iEndY);
            cbNew.EndInit();

            return cbNew;
        }
Пример #8
0
		private static void UpdateCornerImage(Image image, Grid imageHolder, BitmapSource bitmap, RegionChooser regionChooser, bool isRetry = false)
		{
			// Image dimensions
			int imageWidth = bitmap.PixelWidth;
			int imageHeight = bitmap.PixelHeight;

			double availableWidth = imageHolder.ActualWidth;
			double availableHeight = imageHolder.ActualHeight;

			if (availableWidth == 0 || availableHeight == 0)
			{
				// Intermittent bug causing this. In this case we queue it up to go again after a layout pass has been done.
				if (!isRetry)
				{
					DispatchService.BeginInvoke(() =>
						{
							UpdateCornerImage(image, imageHolder, bitmap, regionChooser, isRetry: true);
						});
				}

				return;
			}

			int cornerWidthPixels = (int)(availableWidth / ZoomedPixelSize);
			int cornerHeightPixels = (int)(availableHeight / ZoomedPixelSize);

			// Make sure the subsection of the image is not larger than the image itself
			cornerWidthPixels = Math.Min(cornerWidthPixels, imageWidth);
			cornerHeightPixels = Math.Min(cornerHeightPixels, imageHeight);

			double cornerWidth = cornerWidthPixels * ZoomedPixelSize;
			double cornerHeight = cornerHeightPixels * ZoomedPixelSize;

			var croppedBitmap = new CroppedBitmap();
			croppedBitmap.BeginInit();
			croppedBitmap.SourceRect = regionChooser(imageWidth, imageHeight, cornerWidthPixels, cornerHeightPixels);
			croppedBitmap.Source = bitmap;
			croppedBitmap.EndInit();

			image.Source = croppedBitmap;
			image.Width = cornerWidth;
			image.Height = cornerHeight;
		}