async Task CreateTintEffectBrushAsync(Uri uri) { Xamarin.Forms.Image element = this.Element as Xamarin.Forms.Image; if (Control == null || Element == null || element.Width < 0 || element.Height < 0) { return; } SetupCompositor(); spriteVisual = compositor.CreateSpriteVisual(); spriteVisual.Size = new Vector2((float)element.Width, (float)element.Height); imageSurface = await generator.CreateImageSurfaceAsync(uri, new Windows.Foundation.Size(element.Width, element.Height), ImageSurfaceOptions.DefaultOptimized); CompositionSurfaceBrush surfaceBrush = compositor.CreateSurfaceBrush(imageSurface.Surface); CompositionBrush targetBrush = surfaceBrush; if (this.TintColor == Color.Transparent) { // Don't apply tint effect effectBrush = null; } else { // Set target brush to tint effect brush Windows.UI.Color nativeColor = GetNativeColor(this.TintColor); IGraphicsEffect graphicsEffect = new CompositeEffect { Mode = CanvasComposite.DestinationIn, Sources = { new ColorSourceEffect { Name = "colorSource", Color = nativeColor }, new CompositionEffectSourceParameter("mask") } }; CompositionEffectFactory effectFactory = compositor.CreateEffectFactory(graphicsEffect, new[] { "colorSource.Color" }); effectBrush = effectFactory.CreateBrush(); effectBrush.SetSourceParameter("mask", surfaceBrush); SetTint(nativeColor); targetBrush = effectBrush; } spriteVisual.Brush = targetBrush; ElementCompositionPreview.SetElementChildVisual(Control, spriteVisual); }
/// <summary> /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface /// (using the alpha values of image in the given imageSurface). /// </summary> /// <param name="imageSurface">IImageSurface whose image is to be loaded on the surface.</param> /// <param name="options">Describes the image's resize, alignment options in the allocated space.</param> public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) { if (imageSurface != null) { Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, options); } else { // Draw an empty surface Redraw(surfaceBitmap: null, options); } }
/// <summary> /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface with the given padding. /// </summary> /// <param name="imageSurface">ImageSurface whose image's alpha values are to be used to create the mask.</param> /// <param name="padding">The padding between the IImageMaskSurface outer bounds and the bounds of the area where /// the mask, created from the loaded image's alpha values, should be rendered.</param> public void Redraw(IImageSurface imageSurface, Thickness padding) { if (imageSurface != null) { Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, padding, Options); } else { // Draw an empty surface Redraw(surfaceBitmap: null, Size, padding, Options); } }
/// <summary> /// Redraws the IImageMaskSurface using the alpha values of image in the given imageSurface. /// </summary> /// <param name="imageSurface">IImageSurface whose image is to be loaded on the surface.</param> public void Redraw(IImageSurface imageSurface) { if (imageSurface != null) { Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, MaskPadding, imageSurface.Options); } else { // Draw an empty surface Redraw(surfaceBitmap: null, Size, MaskPadding, Options); } }
private void OnLoaded(object sender, RoutedEventArgs e) { _compositor = Window.Current.Compositor; _generator = _compositor.CreateCompositionGenerator(); _imageVisual = _compositor.CreateSpriteVisual(); _imageVisual.Size = new Vector2(RenderGrid.Width.ToSingle(), RenderGrid.Height.ToSingle()); _imageOptions = ImageSurfaceOptions.DefaultOptimized; _imageOptions.SurfaceBackgroundColor = Colors.Black; _imageSurface = _generator.CreateImageSurface(null, _imageVisual.Size.ToSize(), _imageOptions); _imageVisual.Brush = _compositor.CreateSurfaceBrush(_imageSurface); ElementCompositionPreview.SetElementChildVisual(RenderGrid, _imageVisual); ImageCB.SelectedIndex = 0; StretchCB.SelectedIndex = 0; AlignXCB.SelectedIndex = 1; AlignYCB.SelectedIndex = 1; }
async Task CreateTintEffectBrushAsync(Uri uri) { if (Control == null || Element == null || Element.Width < 0 || Element.Height < 0) { return; } Debug.WriteLine("Creating Tint Effect Brush"); SetupCompositor(); spriteVisual = compositor.CreateSpriteVisual(); spriteVisual.Size = new Vector2((float)Element.Width, (float)Element.Height); imageSurface = await generator.CreateImageSurfaceAsync(uri, new Size(Element.Width, Element.Height), ImageSurfaceOptions.DefaultOptimized); CompositionSurfaceBrush surfaceBrush = compositor.CreateSurfaceBrush(imageSurface.Surface); Windows.UI.Color nativeColor = GetNativeColor(((TintedImage)Element).TintColor); IGraphicsEffect graphicsEffect = new CompositeEffect { Mode = CanvasComposite.DestinationIn, Sources = { new ColorSourceEffect { Name = "colorSource", Color = nativeColor }, new CompositionEffectSourceParameter("mask") } }; CompositionEffectFactory effectFactory = compositor.CreateEffectFactory(graphicsEffect, new[] { "colorSource.Color" }); effectBrush = effectFactory.CreateBrush(); effectBrush.SetSourceParameter("mask", surfaceBrush); SetTint(nativeColor); spriteVisual.Brush = effectBrush; ElementCompositionPreview.SetElementChildVisual(Control, spriteVisual); }
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length < 3) { return(null); } int id; if (values[0] is int) { id = (int)values[0]; } else { return(null); } var manager = values[1] as UODataManager; if (manager == null) { return(null); } if (!(values[2] is ImageType)) { return(null); } var imagetype = (ImageType)values[2]; ISurface item = null; IImageSurface texture = null; switch (imagetype) { case ImageType.Item: { item = manager.GetItemTile(id).Surface; if (item == null) { return(null); } texture = item.GetSurface(); } break; case ImageType.LandTexture: { item = manager.GetLandTile(id).Texture; if (item == null) { return(null); } texture = item.GetSurface(); } break; case ImageType.LandTile: { item = manager.GetLandTile(id).Surface; if (item == null) { return(null); } texture = item.GetSurface(); } break; } if (item == null) { return(null); } return(texture == null ? null : texture.Image); }
private async Task CreateTintEffectBrushAsync(Color color) { if (Control == null || Element == null || Element.Width <= 0 || Element.Height <= 0) { return; } var uri = new Uri($"ms-appx:///{((FileImageSource)Element.Source).File}"); var nativeColor = GetNativeColor(color); SetupCompositor(); _spriteVisual = _compositor.CreateSpriteVisual(); _spriteVisual.Size = new Vector2((float)Element.Width, (float)Element.Height); _imageSurface = await _generator.CreateImageSurfaceAsync( uri, new Size(Element.Width, Element.Height), ImageSurfaceOptions.DefaultOptimized); CompositionSurfaceBrush surfaceBrush = _compositor.CreateSurfaceBrush(_imageSurface.Surface); CompositionBrush targetBrush = surfaceBrush; if (color == Color.Transparent) { // Don't apply tint effect _effectBrush = null; } else { // Set target brush to tint effect brush IGraphicsEffect graphicsEffect = new CompositeEffect { Mode = CanvasComposite.DestinationIn, Sources = { new ColorSourceEffect { Name = "colorSource", Color = nativeColor, }, new CompositionEffectSourceParameter("mask"), }, }; CompositionEffectFactory effectFactory = _compositor.CreateEffectFactory( graphicsEffect, new[] { "colorSource.Color" }); _effectBrush = effectFactory.CreateBrush(); _effectBrush.SetSourceParameter("mask", surfaceBrush); SetTint(nativeColor); targetBrush = _effectBrush; } _spriteVisual.Brush = targetBrush; ElementCompositionPreview.SetElementChildVisual(Control, _spriteVisual); }
//internal static BaseSysFactory Instance { get { return _Instance ?? (_Instance = new BaseSysFactory()); } } //private static BaseSysFactory _Instance; public ISurface CreateSurface(IImageSurface surface) { return(new BitmapSurface(surface)); }
ushort IImageSurface.GetHammingDistanceForAvrHash128(IImageSurface surface) { if (surface == null) { return 0xFFFF; } ushort result = 0; byte[] avrhash1 = null, avrhash2 = null; if (surface is BitmapSurface) avrhash2 = (surface as BitmapSurface).GetAvrHash128(); else throw new NotImplementedException(); avrhash1 = GetAvrHash128(); for (var cb = 0; cb < 128; ++cb) result += _BitCountTable[avrhash1[cb] ^ avrhash2[cb]]; return result; }
ushort IImageSurface.GetHammingDistanceForAvrHash008(IImageSurface surface) { if (surface == null) { return 0xFFFF; } ushort result; ulong avrhash = 0; if (surface is BitmapSurface) avrhash = (surface as BitmapSurface).GetAvrHash008(); else throw new NotImplementedException(); avrhash ^= GetAvrHash008(); result = _BitCountTable[avrhash & 0xFF]; result += _BitCountTable[(avrhash >> 8) & 0xFF]; result += _BitCountTable[(avrhash >> 16) & 0xFF]; result += _BitCountTable[(avrhash >> 24) & 0xFF]; result += _BitCountTable[(avrhash >> 32) & 0xFF]; result += _BitCountTable[(avrhash >> 40) & 0xFF]; result += _BitCountTable[(avrhash >> 48) & 0xFF]; result += _BitCountTable[(avrhash >> 56) & 0xFF]; return result; // avrhash -= (avrhash>>1) & 0x55555555UL; // avrhash = ((avrhash >> 2) & 0x33333333UL) + (avrhash & 0x33333333UL); // avrhash = ((avrhash >> 4) + avrhash) & 0x0f0f0f0fUL; // avrhash *= 0x01010101UL; // return avrhash >> 24; }
/// <summary> /// Loads an image asynchronously from the given object for the given size /// </summary> /// <param name="scheduledObject">The next object to load</param> /// <param name="size">Render size of the image</param> /// <returns>Task</returns> private async Task LoadImageAsync(object scheduledObject, Size size) { try { bool raiseEvent; // Does the ImageFrame contain no previously rendered image? if (_imageSurface == null) { // Since a new object is being loaded, ImageOpened event // must be raised on successful load raiseEvent = true; // Show the placeholder, if required DisplayPlaceHolder(); // Create the ImageSurface and get the uri of the cached object var cachedUri = await LoadNextScheduledObject(scheduledObject, size, false); // Object was successfully cached and loaded if ((cachedUri != null) && (_imageSurface != null)) { // Set initial opacity to 0 so that the contentVisual can be faded in _frameContentVisual.Opacity = 0; // Apply the surfaceBrush to the visual var surfaceBrush = _compositor.CreateSurfaceBrush(_imageSurface.Surface); // Update the surface brush based on the Stretch and Alignment options surfaceBrush.UpdateSurfaceBrushOptions(Stretch, AlignX, AlignY); _frameContentVisual.Brush = surfaceBrush; // Report 100% progress ProgressHandler(100); // Hide the placeholder HidePlaceholder(); // If we are rendering fast, no need to animate if (RenderFast) { _frameContentVisual.Opacity = 1; } else { // Start transition animation StartTransition(true); } } // Caching or Loading of the object failed else { // Clear the existing image ClearImageFrame(); } } else { var hashedUri = await ImageCache.GetHashedUriAsync(scheduledObject); // Check whether the object to load is same as the existing image // loaded in the ImageSurface if (_imageSurface.Uri.IsEqualTo(hashedUri)) { // Since the Uri has not changed, no need to raise the ImageOpened event // Just resize the ImageSurface with the given imageOptions and // update the frameContentVisual's brush raiseEvent = false; _imageSurface.Resize(size, _imageOptions); // Update the surface brush based on the Stretch and Alignment options if (RenderFast) { // Use no animations to update alignment if we are rendering fast (_frameContentVisual.Brush as CompositionSurfaceBrush)?.UpdateSurfaceBrushOptions(Stretch, AlignX, AlignY); } else { // Update stretch and alignment using animation (_frameContentVisual.Brush as CompositionSurfaceBrush)?.UpdateSurfaceBrushOptions(Stretch, AlignX, AlignY, _alignXAnimation, _alignYAnimation); } } else { // Since a different Uri is being loaded, then ImageOpened event // must be raised on successful load raiseEvent = true; // Show the placeholder, if required DisplayPlaceHolder(); // Create a temporary visual which loads the new Uri _nextVisualContent.Opacity = 0; // Load the object scheduled for load var cachedUri = await LoadNextScheduledObject(scheduledObject, size, true); // Object was successfully cached and loaded if (cachedUri != null) { // Create the surface brush for the next image _nextSurfaceBrush = _compositor.CreateSurfaceBrush(_nextImageSurface.Surface); // Update the surface brush based on the Stretch and Alignment options _nextSurfaceBrush.UpdateSurfaceBrushOptions(Stretch, AlignX, AlignY); _nextVisualContent.Brush = _nextSurfaceBrush; // Report 100% progress ProgressHandler(100); // If we are rendering fast, then no need to animate. if (RenderFast) { _frameContentVisual.Opacity = 0; _nextVisualContent.Opacity = 1; // apply the new brush to the frameVisualContent _frameContentVisual.Brush = _nextSurfaceBrush; // Update the surface image _imageSurface = _nextImageSurface; // Make the frameVisualContent visible again _frameContentVisual.Opacity = 1; // Hide the placeholder HidePlaceholder(); // Hide the nextVisualContent _nextVisualContent.Opacity = 0; } else { _compositor.CreateScopedBatch(CompositionBatchTypes.Animation, () => { // Start transition animation StartTransition(false); }, () => { // apply the new brush to the frameVisualContent _frameContentVisual.Brush = _nextSurfaceBrush; // Update the surface image _imageSurface = _nextImageSurface; // Make the frameVisualContent visible again _frameContentVisual.Opacity = 1; // Hide the placeholder HidePlaceholder(); // Hide the nextVisualContent _nextVisualContent.Opacity = 0; }); } } // Caching or Loading of the object failed else { // Clear the existing image ClearImageFrame(); } } } if (raiseEvent) { // Notify to subscribers that the image has been successfully loaded await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ImageOpened?.Invoke(this, new ImageFrameEventArgs(_imageSurface.Uri, string.Empty)); }); } } catch (IOException ex) { // Notify to subscribers that loading of the image failed await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ImageFailed?.Invoke(this, new ImageFrameEventArgs(_currentObject, ex.ToString())); }); } // Update the engineState after load is completed PostLoadImage(); }
/// <summary> /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface /// with the given padding and options. /// </summary> /// <param name="imageSurface">ImageSurface whose image's alpha values are to be used to create the mask.</param> /// <param name="size">New size of the IImageMaskSurface.</param> /// <param name="padding">The padding between the IImageMaskSurface outer bounds and the bounds of the area where /// the mask, created from the loaded image's alpha values, should be rendered.</param> /// <param name="options">Describes the image's resize, alignment and blur radius options in the allocated space.</param> public void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options) { Redraw(imageSurface?.SurfaceBitmap, size, padding, options); }
private void ClearImageFrame() { // Clear the progress in the Placeholder ProgressHandler(-1); if (RenderFast) { // Make the frameVisualContent transparent _frameContentVisual.Brush = _compositor.CreateColorBrush(Colors.Transparent); // Dispose the ImageSurface _imageSurface?.Dispose(); _imageSurface = null; // Engine is now idle _engineState = ImageEngineState.Idle; } else { _compositor.CreateScopedBatch(CompositionBatchTypes.Animation, () => { // Fade out the frameVisualContent _frameContentVisual.StartAnimation(() => _frameContentVisual.Opacity, _fadeOutAnimation); }, () => { // Make the frameVisualContent transparent _frameContentVisual.Brush = _compositor.CreateColorBrush(Colors.Transparent); //await _imageSurface.RedrawAsync(cachedUri, size, _imageOptions); _frameContentVisual.Opacity = 1; // Dispose the ImageSurface _imageSurface?.Dispose(); _imageSurface = null; // Engine is now idle _engineState = ImageEngineState.Idle; }); } }
/// <summary> /// Loads the Uri scheduled for load. If after loading there is another /// Uri scheduled it loads that and keeps on repeating this until there /// are no more Uris scheduled for load. /// </summary> /// <param name="objectToLoad">Object scheduled to be loaded in the ImageFrame</param> /// <param name="size">Size of the ImageSurface</param> /// <param name="isLoadingNext">Whether loading in the imageSurface or the /// nextImageSurface</param> /// <returns>Uri</returns> private async Task<Uri> LoadNextScheduledObject(object objectToLoad, Size size, bool isLoadingNext) { bool loadNext; Uri cachedUri; do { _currentObject = objectToLoad; cachedUri = await ImageCache.GetCachedUriAsync(objectToLoad, ProgressHandler); // Load the new uri if (isLoadingNext) { _nextImageSurface = await _generator.CreateImageSurfaceAsync(cachedUri, size, _imageOptions); } else { _imageSurface = await _generator.CreateImageSurfaceAsync(cachedUri, size, _imageOptions); } // Report 99% progress ProgressHandler(99); // Since the loading of the object takes some time, it could be possible // that a new object has been scheduled for load. In that case, discard // the current object and load the scheduled object if (_engineState == ImageEngineState.Scheduled) { loadNext = true; objectToLoad = _scheduledObject; _engineState = ImageEngineState.Loading; } else { loadNext = false; } } while (loadNext); return cachedUri; }
/// <summary> /// Resizes and redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface /// (using the alpha values of image in the given imageSurface). /// </summary> /// <param name="imageSurface">IImageSurface whose image is to be loaded on the surface.</param> /// <param name="size">New size of the IImageMaskSurface.</param> /// <param name="options">Describes the image's resize, alignment options in the allocated space.</param> public void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options) { Redraw(imageSurface?.SurfaceBitmap, size, options); }
bool ISurface.Equals(IImageSurface surface) { if (Equals((object)surface)) return true; if (surface is BitmapSurface) { return (surface as BitmapSurface).GetHash().SequenceEqual(GetHash()); } else throw new NotImplementedException(); }
async void Redraw(bool recreateSurface = true) { if (_compositor == null) { _compositor = Window.Current.Compositor; _generator = _compositor.CreateCompositionGenerator(); _defaultSize = new Vector2(GridWidth, GridWidth); // Create the original output image visual _originalImageVisual = _compositor.CreateSpriteVisual(); _originalImageVisual.Size = _defaultSize; _imageSurface = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/cat.png"), _defaultSize.ToSize(), ImageSurfaceOptions.Default); _originalImageVisual.Brush = _compositor.CreateSurfaceBrush(_imageSurface); ElementCompositionPreview.SetElementChildVisual(OriginalOutputGrid, _originalImageVisual); // Create the source image visual _sourceImageVisual = _compositor.CreateSpriteVisual(); _sourceImageVisual.Size = _defaultSize; ElementCompositionPreview.SetElementChildVisual(ImageGrid, _sourceImageVisual); //Create the mask visual _maskVisual = _compositor.CreateSpriteVisual(); _maskVisual.Size = _defaultSize; ElementCompositionPreview.SetElementChildVisual(MaskGrid, _maskVisual); // Create the output visual _outputVisual = _compositor.CreateSpriteVisual(); _outputVisual.Size = _defaultSize; ElementCompositionPreview.SetElementChildVisual(OutputGrid, _outputVisual); } var selIndex = ImageList.SelectedIndex; if (selIndex == -1) { return; } var uri = _images.Values.ElementAt(selIndex); if (uri == null) { return; } var offset = OffsetSlider.Value.ToSingle(); var padding = new Thickness(offset); if (recreateSurface) { _sourceImageSurface = await _generator.CreateImageSurfaceAsync(uri, _defaultSize.ToSize(), ImageSurfaceOptions.Default); _imageMaskSurface = _generator.CreateImageMaskSurface(_sourceImageSurface, _defaultSize.ToSize(), padding, ImageSurfaceOptions.GetDefaultImageMaskOptionsForBlur(_blurRadius)); } else { _imageMaskSurface.Resize(_defaultSize.ToSize(), padding, ImageSurfaceOptions.GetDefaultImageMaskOptionsForBlur(_blurRadius)); } _sourceImageVisual.Brush = _compositor.CreateSurfaceBrush(_sourceImageSurface); _maskVisual.Brush = _compositor.CreateSurfaceBrush(_imageMaskSurface); var maskedBrush = _compositor.CreateMaskBrush(); maskedBrush.Source = _originalImageVisual.Brush; maskedBrush.Mask = _compositor.CreateSurfaceBrush(_imageMaskSurface); _outputVisual.Brush = maskedBrush; }
/// <summary> /// Disposes the resources /// </summary> public void Dispose() { // Clean up resources _compositor = null; Source = null; DataContext = null; Foreground = null; Background = null; _scheduledObject = null; _currentObject = null; // Clean up Composition Objects _imageSurface?.Dispose(); _imageSurface = null; _nextImageSurface?.Dispose(); _nextImageSurface = null; _frameLayerMask?.Dispose(); _frameLayerMask = null; _placeholderContentMask?.Dispose(); _placeholderContentMask = null; _placeholderContentBrush?.Dispose(); _placeholderContentBrush = null; _nextSurfaceBrush?.Dispose(); _nextSurfaceBrush = null; _rootContainer?.Dispose(); _rootContainer = null; _shadowVisual?.Dispose(); _shadowVisual = null; _frameLayer?.Dispose(); _frameLayer = null; _frameBackgroundVisual?.Dispose(); _frameBackgroundVisual = null; _placeholderBackgroundVisual?.Dispose(); _placeholderBackgroundVisual = null; _placeholderContentVisual?.Dispose(); _placeholderContentVisual = null; _frameContentVisual?.Dispose(); _frameContentVisual = null; _nextVisualContent?.Dispose(); _nextVisualContent = null; _shadow?.Dispose(); _shadow = null; _layerEffectBrush?.Dispose(); _layerEffectBrush = null; _imageOptions = null; _zoomInAnimationGroup?.Dispose(); _zoomInAnimationGroup = null; _fadeOutAnimation?.Dispose(); _fadeOutAnimation = null; _fadeInAnimation?.Dispose(); _fadeInAnimation = null; _colorAnimation?.Dispose(); _colorAnimation = null; _alignXAnimation?.Dispose(); _alignXAnimation = null; _alignYAnimation?.Dispose(); _alignYAnimation = null; _offsetAnimation?.Dispose(); _offsetAnimation = null; _scaleAnimation?.Dispose(); _scaleAnimation = null; // Dispose the generator at the end to allow the // dependant composition objects to unsubscribe from // generator events _generator?.Dispose(); _generator = null; }