コード例 #1
0
        public static ImageSource SaveThumbnail(ThumbnailOptions options)
        {
            // Make sure this method runs in the UI thread.
            if (!Deployment.Current.Dispatcher.CheckAccess())
            {
                return(Deployment.Current.Dispatcher.Invoke <ImageSource>(() =>
                {
                    return SaveThumbnail(options);
                }));
            }

            // Gets the images.
            WriteableBitmap preferedImage = GetBitmapSource(options.PreferedMedia);
            WriteableBitmap fallbackImage = GetBitmapSource(options.FallbackMedia);

            // Determines which image needs to be saved.
            WriteableBitmap targetImage = preferedImage;

            if (preferedImage == null)
            {
                // Use the fallback image if the prefered image does not exist.
                targetImage = fallbackImage;
            }
            else if (fallbackImage != null && options.MinWidth > -1 && preferedImage.PixelWidth < options.MinWidth && preferedImage.PixelWidth < fallbackImage.PixelWidth)
            {
                // Use the fallback image if its width is bigger than the prefered image's width, the latter being
                // smaller than the min width.
                targetImage = fallbackImage;
            }

            // No image? Return.
            if (targetImage == null)
            {
                return(null);
            }

            // Gets the dimensions of the target image.
            int    targetWidth      = (int)Math.Max(options.MinWidth, targetImage.PixelWidth);
            double sourcePixelRatio = targetImage.PixelWidth / (double)targetImage.PixelHeight;
            int    targetHeight     = (int)Math.Floor(targetWidth / sourcePixelRatio);

            // Blurs the image if needed.
            ExtendedImage targetExtendedImage = null;

            if (options.Blur)
            {
                // Converts the image to an ImageTools image.
                targetExtendedImage = targetImage.ToImage();

                // Resizes the image if it can help decreasing the time needed to blur it.
                // The image is only resized if the target size is less than the original size.
                // Otherwise it means that the original image is smaller than the target size, in which case we blur it
                // as it is and let WP scale up the blurred image later.
                if (targetExtendedImage.PixelHeight * targetExtendedImage.PixelWidth > targetWidth * targetHeight)
                {
                    targetExtendedImage = ExtendedImage.Resize(targetExtendedImage, targetWidth, targetHeight, new ImageTools.Filtering.NearestNeighborResizer());
                }

                // Inits the blur filter if needed and runs it.
                if (_gaussianBlurFilter == null)
                {
                    _gaussianBlurFilter = new ImageTools.Filtering.GaussianBlur()
                    {
                        Variance = 2d
                    };
                }
                targetExtendedImage = ExtendedImage.ApplyFilters(targetExtendedImage, _gaussianBlurFilter);
            }

            // Crops the image if needed.
            if (options.CropRectangle.HasValue)
            {
                if (targetExtendedImage == null)
                {
                    // Converts the image to an ImageTools image.
                    targetExtendedImage = targetImage.ToImage();
                }

                // Computes the downscaled crop rectangle.
                // We're downscaling the crop rectangle instead of upscaling the image and then cropping it,
                // in order to save some time.
                // WP will upscale the cropped image later on.
                int       conformedCropWidth  = Math.Min(options.CropRectangle.Value.Width, targetWidth);
                int       conformedCropHeight = Math.Min(options.CropRectangle.Value.Height, targetHeight);
                double    scaleFactor         = (double)targetExtendedImage.PixelWidth / (double)targetWidth;
                Rectangle crop = options.CropRectangle.Value;
                crop.Width  = (int)(conformedCropWidth * scaleFactor);
                crop.Height = (int)(conformedCropHeight * scaleFactor);
                crop.X      = (int)((double)crop.X * scaleFactor);
                crop.Y      = (int)((double)crop.Y * scaleFactor);

                // Crops the image.
                if (crop.Width > 0 && crop.Height > 0)
                {
                    targetExtendedImage = ExtendedImage.Crop(targetExtendedImage, crop);
                }

                // Stores the final dimensions of the image for later scaling.
                targetWidth  = conformedCropWidth;
                targetHeight = conformedCropHeight;
            }

            if (targetExtendedImage != null)
            {
                targetImage = targetExtendedImage.ToBitmap();
            }

            // Saves the image.
            try
            {
                if (targetWidth > 0 && targetHeight > 0)
                {
                    using (IsolatedStorageFileStream stream = options.IsoStoreFile.OpenFile(options.Filename, FileMode.Create, FileAccess.ReadWrite))
                    {
                        targetImage.SaveJpeg(stream, targetWidth, targetHeight, 0, 100);
                    }
                }
            }
            catch (IsolatedStorageException ex)
            {
                // Nothing to do, let's just dump this for further analysis.
                DebugUtils.DumpException(ex, string.Format("OpenFile(f:{0})", options.Filename), true);
            }
            catch (ArgumentException ex)
            {
                // Nothing to do, let's just dump this for further analysis.
                DebugUtils.DumpException(ex, string.Format("SaveJpeg(w:{0},h:{1})", targetWidth, targetHeight), true);
            }

            // Returns the image.
            return(targetImage);
        }