/// <summary> /// Instantites the <see cref="BitmapMemoryCacheKey"/>. /// </summary> public BitmapMemoryCacheKey( string sourceString, ResizeOptions resizeOptions, bool autoRotated, ImageDecodeOptions imageDecodeOptions, ICacheKey postprocessorCacheKey, string postprocessorName, object callerContext) { _sourceString = Preconditions.CheckNotNull(sourceString); _resizeOptions = resizeOptions; _autoRotated = autoRotated; _imageDecodeOptions = imageDecodeOptions; _postprocessorCacheKey = postprocessorCacheKey; _postprocessorName = postprocessorName; _hash = HashCodeUtil.HashCode( sourceString.GetHashCode(), (resizeOptions != null) ? resizeOptions.GetHashCode() : 0, autoRotated ? true.GetHashCode() : false.GetHashCode(), _imageDecodeOptions, _postprocessorCacheKey, postprocessorName); _callerContext = callerContext; _cacheTime = SystemClock.UptimeMillis; }
/// <summary> /// Sets the builder to be equivalent to the specified options. /// </summary> /// <param name="options">The options to copy from.</param> /// <returns>This builder.</returns> public ImageDecodeOptionsBuilder SetFrom(ImageDecodeOptions options) { DecodePreviewFrame = options.DecodePreviewFrame; UseLastFrameForPreview = options.UseLastFrameForPreview; DecodeAllFrames = options.DecodeAllFrames; ForceStaticImage = options.ForceStaticImage; return(this); }
/// <summary> /// Instantiates the <see cref="ProgressiveDecoder"/>. /// </summary> public ProgressiveDecoder( DecodeProducer parent, IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) : base(consumer) { _parent = parent; _producerContext = producerContext; _producerListener = producerContext.Listener; _imageDecodeOptions = producerContext.ImageRequest.ImageDecodeOptions; _isFinished = false; Func <EncodedImage, bool, Task> job = (encodedImage, isLast) => { if (encodedImage != null) { if (_parent._downsampleEnabled) { ImageRequest request = producerContext.ImageRequest; if (_parent._downsampleEnabledForNetwork || !UriUtil.IsNetworkUri(request.SourceUri)) { encodedImage.SampleSize = DownsampleUtil.DetermineSampleSize( request, encodedImage); } } return(DoDecode(encodedImage, isLast)); } return(Task.CompletedTask); }; _jobScheduler = new JobScheduler( _parent._executor, job, _imageDecodeOptions.MinDecodeIntervalMs); _producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { }, () => { }, () => { if (_producerContext.IsIntermediateResultExpected) { _jobScheduler.ScheduleJob(); } }, () => { })); }
/// <summary> /// Decodes image. /// </summary> /// <param name="encodedImage"> /// Input image (encoded bytes plus meta data). /// </param> /// <param name="length"> /// If image type supports decoding incomplete image then /// determines where the image data should be cut for decoding. /// </param> /// <param name="qualityInfo"> /// Quality information for the image. /// </param> /// <param name="options"> /// Options that cange decode behavior. /// </param> public Task <CloseableImage> DecodeImageAsync( EncodedImage encodedImage, int length, IQualityInfo qualityInfo, ImageDecodeOptions options) { ImageFormat imageFormat = encodedImage.Format; if (imageFormat == ImageFormat.UNINITIALIZED || imageFormat == ImageFormat.UNKNOWN) { imageFormat = ImageFormatChecker.GetImageFormat_WrapIOException( encodedImage.GetInputStream()); encodedImage.Format = imageFormat; } switch (imageFormat) { case ImageFormat.UNKNOWN: throw new ArgumentException("unknown image format"); case ImageFormat.JPEG: return(DecodeJpegAsync(encodedImage, length, qualityInfo) .ContinueWith( task => ((CloseableImage)task.Result), TaskContinuationOptions.ExecuteSynchronously)); case ImageFormat.GIF: return(DecodeGifAsync(encodedImage, options)); case ImageFormat.WEBP_ANIMATED: return(DecodeAnimatedWebpAsync(encodedImage, options)); default: return(DecodeStaticImageAsync(encodedImage) .ContinueWith( task => ((CloseableImage)task.Result), TaskContinuationOptions.ExecuteSynchronously)); } }
/// <summary> /// Decodes gif into CloseableImage. /// </summary> /// <param name="encodedImage"> /// Input image (encoded bytes plus meta data). /// </param> /// <param name="options">Decode options.</param> /// <returns>A CloseableImage.</returns> public Task <CloseableImage> DecodeGifAsync( EncodedImage encodedImage, ImageDecodeOptions options) { Stream inputStream = encodedImage.GetInputStream(); if (inputStream == null) { return(Task.FromResult(default(CloseableImage))); } try { // Phong Cao: always forceStaticImage return(DecodeStaticImageAsync(encodedImage) .ContinueWith( task => ((CloseableImage)task.Result), TaskContinuationOptions.ExecuteSynchronously)); } finally { Closeables.CloseQuietly(inputStream); } }
/// <summary> /// Custom Equals method. /// </summary> public override bool Equals(object o) { if (this == o) { return(true); } if (o == null || GetType() != o.GetType()) { return(false); } ImageDecodeOptions that = (ImageDecodeOptions)o; if (DecodePreviewFrame != that.DecodePreviewFrame) { return(false); } if (UseLastFrameForPreview != that.UseLastFrameForPreview) { return(false); } if (DecodeAllFrames != that.DecodeAllFrames) { return(false); } if (ForceStaticImage != that.ForceStaticImage) { return(false); } return(true); }
/// <summary> /// Decode a webp animated image into a CloseableImage. /// </summary> /// <param name="encodedImage"> /// Input image (encoded bytes plus meta data). /// </param> /// <param name="options">Image decode options.</param> /// <returns>A <see cref="CloseableImage"/>.</returns> public Task <CloseableImage> DecodeAnimatedWebpAsync( EncodedImage encodedImage, ImageDecodeOptions options) { throw new NotImplementedException(); }
/// <summary> /// Sets image decode options. /// </summary> public ImageRequestBuilder SetImageDecodeOptions(ImageDecodeOptions imageDecodeOptions) { ImageDecodeOptions = imageDecodeOptions; return(this); }