예제 #1
0
        public void GetAlphaLevelTests()
        {
            var testEntries = new List <AlphaLevelTest>
            {
                // transparency color tests
                new AlphaLevelTest(new Rectangle(12, 12, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(11, 12, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // last pixel test
                new AlphaLevelTest(new Rectangle(52, 54, 12, 10), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // region out of bound tests
                new AlphaLevelTest(new Rectangle(120, 12, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(12, 120, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(120, 120, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(51, 56, 10, 180), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(51, 56, 100, 7), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(51, 56, 100, 70), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // all image test
                new AlphaLevelTest(new Rectangle(0, 0, 64, 64), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // single pixel tests
                new AlphaLevelTest(new Rectangle(0, 0, 1, 1), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),
                new AlphaLevelTest(new Rectangle(12, 12, 1, 1), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),

                // normal transparency channel tests
                new AlphaLevelTest(new Rectangle(0, 0, 5, 6), null, AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(12, 12, 18, 18), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(1, 30, 5, 14), null, AlphaLevels.MaskAlpha),
                new AlphaLevelTest(new Rectangle(1, 30, 6, 14), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(6, 30, 6, 14), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(1, 47, 5, 14), null, AlphaLevels.MaskAlpha),
                new AlphaLevelTest(new Rectangle(1, 47, 6, 14), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(6, 47, 6, 14), null, AlphaLevels.InterpolatedAlpha)
            };

            var images = new[] { "TransparentRGBA.dds", "TransparentBGRA.dds" };

            foreach (var image in images)
            {
                using (var texTool = new TextureTool())
                    using (var texImage = texTool.Load(Module.PathToInputImages + image))
                    {
                        foreach (var entry in testEntries)
                        {
                            var result = texTool.GetAlphaLevels(texImage, entry.Region, entry.TransparencyColor);
                            Assert.Equal(entry.ExpectedResult, result);
                        }
                    }
            }
        }
예제 #2
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService);

                assetManager.Serializer.RegisterSerializer(new ImageTextureSerializer());

                // Create atlas texture
                Dictionary <SpriteInfo, PackedSpriteInfo> spriteToPackedSprite = null;

                // Generate texture atlas
                var isPacking = Parameters.SheetAsset.Packing.Enabled;

                if (isPacking)
                {
                    var resultStatus = CreateAtlasTextures(commandContext, out spriteToPackedSprite);

                    if (resultStatus != ResultStatus.Successful)
                    {
                        return(Task.FromResult(resultStatus));
                    }
                }

                var imageGroupData = new SpriteSheet();

                // add the sprite data to the sprite list.
                foreach (var image in Parameters.SheetAsset.Sprites)
                {
                    string           textureUrl;
                    RectangleF       region;
                    ImageOrientation orientation;

                    var borders = image.Borders;
                    var center  = image.Center + (image.CenterFromMiddle ? new Vector2(image.TextureRegion.Width, image.TextureRegion.Height) / 2 : Vector2.Zero);

                    if (isPacking &&
                        spriteToPackedSprite.TryGetValue(image, out var packedSprite))    // ensure that unpackable elements (invalid because of null size/texture) are properly added in the sheet using the normal path
                    {
                        var isOriginalSpriteRotated = image.Orientation == ImageOrientation.Rotated90;

                        region      = packedSprite.Region;
                        orientation = (packedSprite.IsRotated ^ isOriginalSpriteRotated) ? ImageOrientation.Rotated90 : ImageOrientation.AsIs;
                        textureUrl  = SpriteSheetAsset.BuildTextureAtlasUrl(Url, spriteToPackedSprite[image].AtlasTextureIndex);

                        // update the center and border info, if the packer rotated the sprite
                        // note: X->Left, Y->Top, Z->Right, W->Bottom.
                        if (packedSprite.IsRotated)
                        {
                            // turned the sprite CCW
                            if (isOriginalSpriteRotated)
                            {
                                var oldCenterX = center.X;
                                center.X = center.Y;
                                center.Y = region.Height - oldCenterX;

                                var oldBorderW = borders.W;
                                borders.W = borders.X;
                                borders.X = borders.Y;
                                borders.Y = borders.Z;
                                borders.Z = oldBorderW;
                            }
                            else // turned the sprite CW
                            {
                                var oldCenterX = center.X;
                                center.X = region.Width - center.Y;
                                center.Y = oldCenterX;

                                var oldBorderW = borders.W;
                                borders.W = borders.Z;
                                borders.Z = borders.Y;
                                borders.Y = borders.X;
                                borders.X = oldBorderW;
                            }
                        }
                    }
                    else
                    {
                        region      = image.TextureRegion;
                        orientation = image.Orientation;
                        Parameters.ImageToTextureUrl.TryGetValue(image, out textureUrl);
                    }

                    // Affect the texture
                    Texture texture = null;
                    if (textureUrl != null)
                    {
                        texture = AttachedReferenceManager.CreateProxyObject <Texture>(AssetId.Empty, textureUrl);
                    }
                    else
                    {
                        commandContext.Logger.Warning($"Image '{image.Name}' has an invalid image source file '{image.Source}', resulting texture will be null.");
                    }

                    imageGroupData.Sprites.Add(new Graphics.Sprite
                    {
                        Name          = image.Name,
                        Region        = region,
                        Orientation   = orientation,
                        Center        = center,
                        Borders       = borders,
                        PixelsPerUnit = new Vector2(image.PixelsPerUnit),
                        Texture       = texture,
                        IsTransparent = false,
                    });
                }

                // set the transparency information to all the sprites
                if (Parameters.SheetAsset.Alpha != AlphaFormat.None) // Skip the calculation when format is forced without alpha.
                {
                    var urlToTexImage = new Dictionary <string, Tuple <TexImage, Image> >();
                    using (var texTool = new TextureTool())
                    {
                        foreach (var sprite in imageGroupData.Sprites)
                        {
                            if (sprite.Texture == null) // the sprite texture is invalid
                            {
                                continue;
                            }

                            var textureUrl = AttachedReferenceManager.GetOrCreateAttachedReference(sprite.Texture).Url;
                            if (!urlToTexImage.ContainsKey(textureUrl))
                            {
                                var image       = assetManager.Load <Image>(textureUrl);
                                var newTexImage = texTool.Load(image, false); // the sRGB mode does not impact on the alpha level
                                texTool.Decompress(newTexImage, false);       // the sRGB mode does not impact on the alpha level
                                urlToTexImage[textureUrl] = Tuple.Create(newTexImage, image);
                            }
                            var texImage = urlToTexImage[textureUrl].Item1;

                            var region = new Rectangle
                            {
                                X = (int)Math.Floor(sprite.Region.X),
                                Y = (int)Math.Floor(sprite.Region.Y)
                            };
                            region.Width  = (int)Math.Ceiling(sprite.Region.Right) - region.X;
                            region.Height = (int)Math.Ceiling(sprite.Region.Bottom) - region.Y;

                            var alphaLevel = texTool.GetAlphaLevels(texImage, region, null, commandContext.Logger); // ignore transparent color key here because the input image has already been processed
                            sprite.IsTransparent = alphaLevel != AlphaLevels.NoAlpha;
                        }

                        // free all the allocated images
                        foreach (var tuple in urlToTexImage.Values)
                        {
                            tuple.Item1.Dispose();
                            assetManager.Unload(tuple.Item2);
                        }
                    }
                }

                // save the imageData into the data base
                assetManager.Save(Url, imageGroupData);

                return(Task.FromResult(ResultStatus.Successful));
            }
예제 #3
0
        public void GetAlphaLevelTests()
        {
            var testEntries = new List<AlphaLevelTest>
            {
                // transparency color tests
                new AlphaLevelTest(new Rectangle(12, 12, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(11, 12, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // last pixel test
                new AlphaLevelTest(new Rectangle(52, 54, 12, 10), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),
                
                // region out of bound tests
                new AlphaLevelTest(new Rectangle(120, 12, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(12, 120, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(120, 120, 18, 18), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(51, 56, 10, 180), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(51, 56, 100, 7), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(51, 56, 100, 70), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // all image test
                new AlphaLevelTest(new Rectangle(0, 0, 64, 64), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),

                // single pixel tests
                new AlphaLevelTest(new Rectangle(0, 0, 1, 1), new Color(255, 81, 237, 255), AlphaLevels.MaskAlpha),
                new AlphaLevelTest(new Rectangle(12, 12, 1, 1), new Color(255, 81, 237, 255), AlphaLevels.NoAlpha),

                // normal transparency channel tests
                new AlphaLevelTest(new Rectangle(0, 0, 5, 6), null, AlphaLevels.NoAlpha),
                new AlphaLevelTest(new Rectangle(12, 12, 18, 18), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(1, 30, 5, 14), null, AlphaLevels.MaskAlpha),
                new AlphaLevelTest(new Rectangle(1, 30, 6, 14), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(6, 30, 6, 14), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(1, 47, 5, 14), null, AlphaLevels.MaskAlpha),
                new AlphaLevelTest(new Rectangle(1, 47, 6, 14), null, AlphaLevels.InterpolatedAlpha),
                new AlphaLevelTest(new Rectangle(6, 47, 6, 14), null, AlphaLevels.InterpolatedAlpha)
            };

            var images = new[] { "TransparentRGBA.dds", "TransparentBGRA.dds" };

            foreach (var image in images)
            {
                using (var texTool = new TextureTool())
                using (var texImage = texTool.Load(Module.PathToInputImages + image))
                {
                    foreach (var entry in testEntries)
                    {
                        var result = texTool.GetAlphaLevels(texImage, entry.Region, entry.TransparencyColor);
                        Assert.AreEqual(entry.ExpectedResult, result);
                    }
                }
            }
        }
예제 #4
0
파일: TextureHelper.cs 프로젝트: zetz/xenko
        public static ResultStatus ImportTextureImage(TextureTool textureTool, TexImage texImage, ImportParameters parameters, CancellationToken cancellationToken, Logger logger)
        {
            var assetManager = new ContentManager();

            // Apply transformations
            textureTool.Decompress(texImage, parameters.IsSRgb);

            // Special case when the input texture is monochromatic but it is supposed to be a color and we are working in SRGB
            // In that case, we need to transform it to a supported SRGB format (R8G8B8A8_UNorm_SRgb)
            // TODO: As part of a conversion phase, this code may be moved to a dedicated method in this class at some point
            if (parameters.TextureHint == TextureHint.Color && parameters.IsSRgb && (texImage.Format == PixelFormat.R8_UNorm || texImage.Format == PixelFormat.A8_UNorm))
            {
                textureTool.Convert(texImage, PixelFormat.R8G8B8A8_UNorm_SRgb);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            var fromSize   = new Size2(texImage.Width, texImage.Height);
            var targetSize = parameters.DesiredSize;

            // Resize the image
            if (parameters.IsSizeInPercentage)
            {
                targetSize = new Size2((int)(fromSize.Width * targetSize.Width / 100.0f), (int)(fromSize.Height * targetSize.Height / 100.0f));
            }

            // Find the target size
            targetSize = FindBestTextureSize(parameters, targetSize, logger);

            // Resize the image only if needed
            if (targetSize != fromSize)
            {
                textureTool.Resize(texImage, targetSize.Width, targetSize.Height, Filter.Rescaling.Lanczos3);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            // texture size is now determined, we can cache it
            var textureSize = new Int2(texImage.Width, texImage.Height);

            // determine the alpha format of the texture when set to Auto
            // Note: this has to be done before the ColorKey transformation in order to be able to take advantage of image file AlphaDepth information
            if (parameters.DesiredAlpha == AlphaFormat.Auto)
            {
                var colorKey   = parameters.ColorKeyEnabled? (Color?)parameters.ColorKeyColor : null;
                var alphaLevel = textureTool.GetAlphaLevels(texImage, new Rectangle(0, 0, textureSize.X, textureSize.Y), colorKey, logger);
                parameters.DesiredAlpha = alphaLevel.ToAlphaFormat();
            }

            // Apply the color key
            if (parameters.ColorKeyEnabled)
            {
                textureTool.ColorKey(texImage, parameters.ColorKeyColor);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            // Pre-multiply alpha only for relevant formats
            if (parameters.PremultiplyAlpha && texImage.Format.HasAlpha32Bits())
            {
                textureTool.PreMultiplyAlpha(texImage);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }


            // Generate mipmaps
            if (parameters.GenerateMipmaps)
            {
                var boxFilteringIsSupported = !texImage.Format.IsSRgb() || (MathUtil.IsPow2(textureSize.X) && MathUtil.IsPow2(textureSize.Y));
                textureTool.GenerateMipMaps(texImage, boxFilteringIsSupported? Filter.MipMapGeneration.Box: Filter.MipMapGeneration.Linear);
            }

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }


            // Convert/Compress to output format
            // TODO: Change alphaFormat depending on actual image content (auto-detection)?
            var outputFormat = DetermineOutputFormat(parameters, textureSize, texImage.Format);

            textureTool.Compress(texImage, outputFormat, (TextureConverter.Requests.TextureQuality)parameters.TextureQuality);

            if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
            {
                return(ResultStatus.Cancelled);
            }

            // Save the texture
            using (var outputImage = textureTool.ConvertToXenkoImage(texImage))
            {
                if (cancellationToken.IsCancellationRequested) // abort the process if cancellation is demanded
                {
                    return(ResultStatus.Cancelled);
                }

                assetManager.Save(parameters.OutputUrl, outputImage.ToSerializableVersion());

                logger.Verbose("Compression successful [{3}] to ({0}x{1},{2})", outputImage.Description.Width, outputImage.Description.Height, outputImage.Description.Format, parameters.OutputUrl);
            }

            return(ResultStatus.Successful);
        }