예제 #1
0
        /// <summary>
        /// Load the image and transform it to a composition brush or a XAML brush (depends of the UIStrategy)
        /// </summary>
        /// <param name="uri">the uri of the image to load</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        private async Task <bool> LoadImageBrush(Uri uri)
        {
            var strategy = Strategy;

            if (strategy == UIStrategy.Composition)
            {
                if (_containerVisual == null || uri == null)
                {
                    return(false);
                }
            }
            else
            {
                if (uri == null)
                {
                    return(false);
                }
            }

            await _flag.WaitAsync();

            try
            {
                bool isAnimated = IsAnimated;

                IsAnimated = false;

                if (_isImageSourceLoaded == true)
                {
                    for (int i = 0; i < _compositionChildren.Count; i++)
                    {
                        if (strategy == UIStrategy.PureXaml)
                        {
                            _xamlChildren[i].Fill = null;
                        }
                        else
                        {
                            _compositionChildren[i].Brush = null;
                        }
                    }

                    if (strategy == UIStrategy.Composition)
                    {
                        _brushVisual.Dispose();
                        _brushVisual = null;

                        _uriSurface.Dispose();
                        _uriSurface = null;
                    }
                }

                _isImageSourceLoaded = false;

                if (strategy == UIStrategy.Composition)
                {
                    var compositor = _containerVisual.Compositor;

                    using (var surfaceFactory = SurfaceFactory.GetSharedSurfaceFactoryForCompositor(compositor))
                    {
                        var surfaceUri = await surfaceFactory.CreateUriSurfaceAsync(uri);

                        _uriSurface  = surfaceUri;
                        _brushVisual = compositor.CreateSurfaceBrush(surfaceUri.Surface);

                        _imageSize = surfaceUri.Size;
                    }
                }
                else
                {
                    BitmapImage image = new BitmapImage();

                    var storageFile = await StorageFile.GetFileFromApplicationUriAsync(uri);

                    using (var stream = await storageFile.OpenReadAsync())
                    {
                        image.SetSource(stream);
                    }

                    _brushXaml = new ImageBrush()
                    {
                        ImageSource = image
                    };
                    _imageSize = new Size(image.PixelWidth, image.PixelHeight);
                }

                _isImageSourceLoaded = true;

                RefreshContainerTile();

                RefreshImageSize(_imageSize.Width, _imageSize.Height);

                if (isAnimated == true)
                {
                    IsAnimated = true;
                }
            }
            finally
            {
                _flag.Release();
            }

            ImageLoaded?.Invoke(this, EventArgs.Empty);

            return(true);
        }
예제 #2
0
        private unsafe short ReadPixelsProc(IntPtr port, ref PSScaling scaling, ref VRect writeRect, ref PixelMemoryDesc destination, ref VRect wroteRect)
        {
#if DEBUG
            DebugUtils.Ping(DebugFlags.ChannelPorts, string.Format("port: {0}, rect: {1}", port.ToString(), writeRect.ToString()));
#endif

            if (destination.depth != 8 && destination.depth != 16)
            {
                return(PSError.errUnsupportedDepth);
            }

            // The offsets must be aligned to a System.Byte.
            if ((destination.bitOffset % 8) != 0)
            {
                return(PSError.errUnsupportedBitOffset);
            }

            if ((destination.colBits % 8) != 0)
            {
                return(PSError.errUnsupportedColBits);
            }

            if ((destination.rowBits % 8) != 0)
            {
                return(PSError.errUnsupportedRowBits);
            }

            int channel = port.ToInt32();

            if (channel < PSConstants.ChannelPorts.Gray || channel > PSConstants.ChannelPorts.SelectionMask)
            {
                return(PSError.errUnknownPort);
            }

            VRect srcRect = scaling.sourceRect;
            VRect dstRect = scaling.destinationRect;

            int         srcWidth    = srcRect.right - srcRect.left;
            int         srcHeight   = srcRect.bottom - srcRect.top;
            int         dstWidth    = dstRect.right - dstRect.left;
            int         dstHeight   = dstRect.bottom - dstRect.top;
            bool        isSelection = channel == PSConstants.ChannelPorts.SelectionMask;
            SurfaceBase source      = filterImageProvider.Source;

            if ((source.BitsPerChannel == 8 || isSelection) && destination.depth == 16)
            {
                return(PSError.errUnsupportedDepthConversion); // converting 8-bit image data to 16-bit is not supported.
            }

            if (isSelection)
            {
                if (srcWidth == dstWidth && srcHeight == dstHeight)
                {
                    FillSelectionMask(destination, filterImageProvider.Mask, srcRect);
                }
                else if (dstWidth < srcWidth || dstHeight < srcHeight) // scale down
                {
                    if ((scaledSelectionMask == null) || scaledSelectionMask.Width != dstWidth || scaledSelectionMask.Height != dstHeight)
                    {
                        if (scaledSelectionMask != null)
                        {
                            scaledSelectionMask.Dispose();
                            scaledSelectionMask = null;
                        }

                        try
                        {
                            scaledSelectionMask = new SurfaceGray8(dstWidth, dstHeight);
                            scaledSelectionMask.SuperSampleFitSurface(filterImageProvider.Mask);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }
                    }

                    FillSelectionMask(destination, scaledSelectionMask, dstRect);
                }
                else if (dstWidth > srcWidth || dstHeight > srcHeight) // scale up
                {
                    if ((scaledSelectionMask == null) || scaledSelectionMask.Width != dstWidth || scaledSelectionMask.Height != dstHeight)
                    {
                        if (scaledSelectionMask != null)
                        {
                            scaledSelectionMask.Dispose();
                            scaledSelectionMask = null;
                        }

                        try
                        {
                            scaledSelectionMask = new SurfaceGray8(dstWidth, dstHeight);
                            scaledSelectionMask.BicubicFitSurface(filterImageProvider.Mask);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }
                    }

                    FillSelectionMask(destination, scaledSelectionMask, dstRect);
                }
            }
            else
            {
                ImageModes mode = imageMode;

                if (source.BitsPerChannel == 16 && destination.depth == 8)
                {
                    if (ditheredChannelSurface == null)
                    {
                        short err = CreateDitheredChannelPortSurface(source);
                        if (err != PSError.noErr)
                        {
                            return(err);
                        }
                    }
                    mode = ditheredChannelImageMode;
                }

                if (srcWidth == dstWidth && srcHeight == dstHeight)
                {
                    FillChannelData(channel, destination, ditheredChannelSurface ?? source, srcRect, mode);
                }
                else if (dstWidth < srcWidth || dstHeight < srcHeight) // scale down
                {
                    if ((scaledChannelSurface == null) || scaledChannelSurface.Width != dstWidth || scaledChannelSurface.Height != dstHeight)
                    {
                        if (scaledChannelSurface != null)
                        {
                            scaledChannelSurface.Dispose();
                            scaledChannelSurface = null;
                        }

                        try
                        {
                            scaledChannelSurface = SurfaceFactory.CreateFromImageMode(dstWidth, dstHeight, mode);
                            scaledChannelSurface.SuperSampleFitSurface(ditheredChannelSurface ?? source);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }

#if DEBUG
                        using (System.Drawing.Bitmap bmp = scaledChannelSurface.ToGdipBitmap())
                        {
                        }
#endif
                    }

                    FillChannelData(channel, destination, scaledChannelSurface, dstRect, mode);
                }
                else if (dstWidth > srcWidth || dstHeight > srcHeight) // scale up
                {
                    if ((scaledChannelSurface == null) || scaledChannelSurface.Width != dstWidth || scaledChannelSurface.Height != dstHeight)
                    {
                        if (scaledChannelSurface != null)
                        {
                            scaledChannelSurface.Dispose();
                            scaledChannelSurface = null;
                        }

                        try
                        {
                            scaledChannelSurface = SurfaceFactory.CreateFromImageMode(dstWidth, dstHeight, mode);
                            scaledChannelSurface.BicubicFitSurface(ditheredChannelSurface ?? source);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }
                    }

                    FillChannelData(channel, destination, scaledChannelSurface, dstRect, mode);
                }
            }

            wroteRect = dstRect;

            return(PSError.noErr);
        }
예제 #3
0
        private void SetupCameraControl()
        {
            // Unregister
            if (_cameraControl != null)
            {
                SizeChanged -= OnSizeChanged;
            }

            // Get template part
            _cameraControl = (CameraControl)GetTemplateChild(CAMERACONTROL_NAME);

            // Bail if missing
            if (_cameraControl == null)
            {
                return;
            }

            SizeChanged += OnSizeChanged;

            // Camera setup
            _cameraControl.SetAsPerspective(RenderSize.ToVector2());
            _cameraControl.Yaw   = 0;
            _cameraControl.Pitch = 0;
            _cameraControl.PerspectiveDistance = 575;
            _cameraControl.Position            = new Vector3(1920 / 2, 1080 / 2, 0);

            // ImageLoader
            _compositor     = _cameraControl.CompositionCamera.CameraVisual.Compositor;
            _surfaceFactory = SurfaceFactory.GetSharedSurfaceFactoryForCompositor(_compositor);

            // Skybox container
            var halfSkyboxSize         = _skyboxSize / 2;
            var negativeHalfSkyboxSize = -_skyboxSize / 2;

            _skyboxContainer              = _compositor.CreateContainerVisual();
            _skyboxContainer.CenterPoint  = new Vector3(halfSkyboxSize, halfSkyboxSize, halfSkyboxSize);
            _skyboxContainer.AnchorPoint  = new Vector2(halfSkyboxSize, halfSkyboxSize);
            _skyboxContainer.Offset       = new Vector3(negativeHalfSkyboxSize, negativeHalfSkyboxSize, negativeHalfSkyboxSize);
            _skyboxContainer.RotationAxis = _rotationAxisY;
            _skyboxContainer.BorderMode   = CompositionBorderMode.Hard;
            _skyboxContainer.Comment      = "Skybox";

            // Skybox sides
            SetupSkyboxSide(SkyboxSide.Top);
            SetupSkyboxSide(SkyboxSide.Left);
            SetupSkyboxSide(SkyboxSide.Right);
            SetupSkyboxSide(SkyboxSide.Bottom);
            SetupSkyboxSide(SkyboxSide.Front);
            SetupSkyboxSide(SkyboxSide.Back);

            // World root
            SpriteVisual treeRoot  = _compositor.CreateSpriteVisual();
            SpriteVisual worldRoot = _compositor.CreateSpriteVisual();

            treeRoot.Comment  = "TreeRoot";
            worldRoot.Comment = "WorldRoot";

            ElementCompositionPreview.SetElementChildVisual(_cameraControl, treeRoot);
            treeRoot.Children.InsertAtTop(worldRoot);
            worldRoot.Children.InsertAtTop(_skyboxContainer);

            if (AutoRotate)
            {
                // Animate for fun.
                Rotate(360, 100000);
            }
        }