Example #1
0
        internal static bool packSprites(string sheetFile, string mapFile = "")
        {
            bool result = true;
            // generate our output
            ImagePacker imagePacker = new ImagePacker();
            Bitmap      outputSheet;
            Dictionary <string, Rectangle> outputMap;

            try
            {
                // pack the image, generating a map only if desired
                if (imagePacker.PackImage(images, false, true, 1024, 1024, 3, mapFile != "", out outputSheet, out outputMap) == 0)
                {
                    outputSheet.Save(sheetFile);
                    if (mapFile != "")
                    {
                        saveMap(mapFile, outputMap);
                    }
                    Console.WriteLine("Generated Sprite Sheet: {0}.", sheetFile);
                }
                else
                {
                    Console.WriteLine("There was an error making the image sheet {0}.", sheetFile);
                    result = false;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error saving sheet: {0} {1}", sheetFile, e.Message);
                result = false;
            }
            return(result);
        }
Example #2
0
        public override AtlasContent Process(AtlasDeclaration input, ContentProcessorContext context)
        {
            Dictionary <int, Bitmap> images     = new Dictionary <int, Bitmap>();
            Dictionary <int, string> imageNames = new Dictionary <int, string>();


            ImagePacker imagePacker = new ImagePacker();
            var         imgFiles    = input.Images.Select(i => Path.Combine(input.AtlasRootDir, i.Replace('/', '\\')));

            if (imgFiles.Count() == 0)
            {
                throw new ArgumentException("No Image found");
            }
            Bitmap output;
            Dictionary <string, Sprite> map;

            imagePacker.PackImage(imgFiles, true, true, 4096, 4096, 0, true, out output, out map);


            var finalSprites = map.Select(s => { s.Value.Name = s.Key.Substring(0, s.Key.LastIndexOf('.')).Substring(input.AtlasRootDir.Length + 1).Replace('\\', '/').Trim('.', '/'); return(s.Value); }).ToArray();
            var atlasPngPath = Path.Combine(input.AtlasRootDir, input.Name + ".png");

            using (FileStream outputSpriteFile = new FileStream(atlasPngPath, FileMode.Create))
            {
                output.Save(outputSpriteFile, ImageFormat.Png);
            }
            context.AddOutputFile(atlasPngPath);
            ExternalReference <TextureContent> texture = new ExternalReference <TextureContent>(atlasPngPath);

            texture = BuildTexture($"{input.Name}Texture", texture, context);

            return(new AtlasContent {
                Texture = texture, Sprites = finalSprites
            });
        }
        /// <inheritdoc />
        public virtual async Task <Result <IWebhook> > ModifyWebhookWithTokenAsync
        (
            Snowflake webhookID,
            string token,
            Optional <string> name    = default,
            Optional <Stream?> avatar = default,
            CancellationToken ct      = default
        )
        {
            var packAvatar = await ImagePacker.PackImageAsync(avatar, ct);

            if (!packAvatar.IsSuccess)
            {
                return(Result <IWebhook> .FromError(new GenericError("Failed to pack avatar."), packAvatar));
            }

            var avatarData = packAvatar.Entity;

            return(await _discordHttpClient.PatchAsync <IWebhook>
                   (
                       $"webhooks/{webhookID}/{token}",
                       b => b.WithJson
                       (
                           json =>
            {
                json.Write("name", name, _jsonOptions);
                json.Write("avatar", avatarData, _jsonOptions);
            }
                       ),
                       ct : ct
                   ));
        }
        /// <inheritdoc />
        public virtual async Task <Result <IGuild> > CreateGuildAsync
        (
            string name,
            Optional <Stream> icon = default,
            Optional <VerificationLevel> verificationLevel = default,
            Optional <MessageNotificationLevel> defaultMessageNotifications = default,
            Optional <ExplicitContentFilterLevel> explicitContentFilter     = default,
            Optional <IReadOnlyList <IRole> > roles = default,
            Optional <IReadOnlyList <IPartialChannel> > channels = default,
            Optional <Snowflake> afkChannelID                = default,
            Optional <TimeSpan> afkTimeout                   = default,
            Optional <Snowflake> systemChannelID             = default,
            Optional <SystemChannelFlags> systemChannelFlags = default,
            CancellationToken ct = default
        )
        {
            if (name.Length < 2 || name.Length > 100)
            {
                return(new GenericError("The name must be between 2 and 100 characters."));
            }

            await using var memoryStream = new MemoryStream();

            var packIcon = await ImagePacker.PackImageAsync(new Optional <Stream?>(icon.Value), ct);

            if (!packIcon.IsSuccess)
            {
                return(Result <IGuild> .FromError(new GenericError("Failed to pack icon."), packIcon));
            }

            var iconData = packIcon.Entity;

            return(await _discordHttpClient.PostAsync <IGuild>
                   (
                       "guilds",
                       b => b.WithJson
                       (
                           json =>
            {
                json.WriteString("name", name);
                json.Write("icon", iconData, _jsonOptions);
                json.Write("verification_level", verificationLevel, _jsonOptions);
                json.Write("default_message_notifications", defaultMessageNotifications, _jsonOptions);
                json.Write("explicit_content_filter", explicitContentFilter, _jsonOptions);
                json.Write("roles", roles, _jsonOptions);
                json.Write("channels", channels, _jsonOptions);
                json.Write("afk_channel_id", afkChannelID, _jsonOptions);

                if (afkTimeout.HasValue)
                {
                    json.WriteNumber("afk_timeout", (ulong)afkTimeout.Value.TotalSeconds);
                }

                json.Write("system_channel_id", systemChannelID, _jsonOptions);
                json.Write("system_channel_flags", systemChannelFlags, _jsonOptions);
            }
                       ),
                       ct : ct
                   ));
        }
Example #5
0
        public void PackWithNoBufferMosiacTests(RectInt[] rects, int padding, Vector2Int expectedSize)
        {
            RectInt[] packedRect;
            int       packedWidth, packedHeight;

            ImagePacker.Pack(rects, padding, out packedRect, out packedWidth, out packedHeight);
            Assert.AreEqual(expectedSize.x, packedWidth);
            Assert.AreEqual(expectedSize.y, packedHeight);
            Assert.AreEqual(rects.Length, packedRect.Length);

            // Ensure all rects exists
            for (int i = 0; i < packedRect.Length; ++i)
            {
                // Ensure rect doesn't overlap with other rects
                RectInt testRect = packedRect[i];
                for (int k = i + 1; k < packedRect.Length; ++k)
                {
                    RectInt other    = packedRect[k];
                    var     contains = !((other.xMax + padding <= testRect.xMin ||
                                          other.yMax + padding <= testRect.yMin) ||
                                         (other.xMin >= testRect.xMax + padding ||
                                          other.yMin >= testRect.yMax + padding));
                    Assert.IsFalse(contains);
                }

                // Ensure rects has the correct padding
                Assert.AreEqual(rects[i].width, testRect.width);
                Assert.AreEqual(rects[i].height, testRect.height);
            }
        }
        /// <inheritdoc />
        public virtual async Task <Result <IWebhook> > ModifyWebhookAsync
        (
            Snowflake webhookID,
            Optional <string> name         = default,
            Optional <Stream?> avatar      = default,
            Optional <Snowflake> channelID = default,
            CancellationToken ct           = default
        )
        {
            var packAvatar = await ImagePacker.PackImageAsync(avatar, ct);

            if (!packAvatar.IsSuccess)
            {
                return(Result <IWebhook> .FromError(packAvatar));
            }

            var avatarData = packAvatar.Entity;

            return(await this.DiscordHttpClient.PatchAsync <IWebhook>
                   (
                       $"webhooks/{webhookID}",
                       b => b.WithJson
                       (
                           json =>
            {
                json.Write("name", name, this.JsonOptions);
                json.Write("avatar", avatarData, this.JsonOptions);
                json.Write("channel_id", channelID, this.JsonOptions);
            }
                       ),
                       ct : ct
                   ));
        }
Example #7
0
        public MainPage()
        {
            InitializeComponent();

            _syncContext = SynchronizationContext.Current;

            PageModel            = new MainPageModel(_syncContext);
            MainGrid.DataContext = PageModel;

            _loadPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "touhou_luna_nights");
            if (!Directory.Exists(_loadPath))
            {
                Directory.CreateDirectory(_loadPath);
            }
            _save0Path = Path.Combine(_loadPath, "game0.sav");
            _save1Path = Path.Combine(_loadPath, "game1.sav");
            _save2Path = Path.Combine(_loadPath, "game2.sav");

            _saveEditor  = new SaveEditor();
            _imagePacker = new ImagePacker(_syncContext);

            ErrorTracker.UpdateError += ErrorTrackerUpdateError;

            Task.Run(ProcessCurrentSaves);
        }
Example #8
0
        /// <inheritdoc />
        public virtual async Task <Result <IUser> > ModifyCurrentUserAsync
        (
            Optional <string> username,
            Optional <Stream?> avatar = default,
            CancellationToken ct      = default
        )
        {
            var packAvatar = await ImagePacker.PackImageAsync(avatar, ct);

            if (!packAvatar.IsSuccess)
            {
                return(Result <IUser> .FromError(packAvatar));
            }

            var avatarData = packAvatar.Entity;

            return(await this.DiscordHttpClient.PatchAsync <IUser>
                   (
                       "users/@me",
                       b => b.WithJson
                       (
                           json =>
            {
                json.Write("username", username, this.JsonOptions);
                json.Write("avatar", avatarData, this.JsonOptions);
            }
                       ),
                       ct : ct
                   ));
        }
        /// <inheritdoc />
        public virtual async Task <Result <IGuild> > CreateGuildFromTemplateAsync
        (
            string templateCode,
            string name,
            Optional <Stream> icon = default,
            CancellationToken ct   = default
        )
        {
            var packIcon = await ImagePacker.PackImageAsync(new Optional <Stream?>(icon.Value), ct);

            if (!packIcon.IsSuccess)
            {
                return(Result <IGuild> .FromError(new GenericError("Failed to pack icon."), packIcon));
            }

            var iconData = packIcon.Entity;

            return(await _discordHttpClient.PostAsync <IGuild>
                   (
                       $"guilds/templates/{templateCode}",
                       b => b.WithJson
                       (
                           j =>
            {
                j.WriteString("name", name);
                j.Write("icon", iconData);
            }
                       ),
                       ct : ct
                   ));
        }
            public async Task CanPackGIFAsync()
            {
                // Create a dummy GIF image
                await using var image        = new MemoryStream();
                await using var binaryWriter = new BinaryWriter(image);
                binaryWriter.Write(0x00464947);
                image.Position = 0;

                var result = await ImagePacker.PackImageAsync(image);

                ResultAssert.Successful(result);
            }
            public async Task CanPackPNGAsync()
            {
                // Create a dummy PNG image
                await using var image        = new MemoryStream();
                await using var binaryWriter = new BinaryWriter(image);
                binaryWriter.Write(9894494448401390090);
                image.Position = 0;

                var result = await ImagePacker.PackImageAsync(image);

                ResultAssert.Successful(result);
            }
            public async Task ReturnsErrorIfFormatIsUnknown()
            {
                // Create a dummy unknown image
                await using var image        = new MemoryStream();
                await using var binaryWriter = new BinaryWriter(image);
                binaryWriter.Write(0x00000000);
                image.Position = 0;

                var result = await ImagePacker.PackImageAsync(image);

                ResultAssert.Unsuccessful(result);
            }
Example #13
0
    public static int Pack(string atlasDir, string imageOutputDir, string codeOutputDir, Func <string, string> namingFunc)
    {
        string imgFile  = Path.Combine(imageOutputDir, "Atlas.png");
        string codeFile = Path.Combine(codeOutputDir, "Atlas.cs");

        // find all images
        List <string> images = new List <string>();

        foreach (var file in Directory.GetFiles(atlasDir, "*.*", SearchOption.AllDirectories))
        {
            FileInfo info = new FileInfo(file);
            if (info.Extension == ".png")
            {
                images.Add(info.FullName);
            }
        }

        // PACKIT!
        var    imagePacker = new ImagePacker();
        Bitmap outputImage;
        Dictionary <string, Rectangle> outputMap;
        int result = imagePacker.PackImage(images, true, true, MAXIMGSIZE, MAXIMGSIZE, 1, true, out outputImage, out outputMap);

        if (result != 0)
        {
            Dbg.Write("There was an error making the image sheet.");
            return(result);
        }

        if (File.Exists(imgFile))
        {
            File.Delete(imgFile);
        }
        IImageExporter imageExporter = new PngImageExporter();

        imageExporter.Save(imgFile, outputImage);

        if (File.Exists(codeFile))
        {
            File.Delete(codeFile);
        }
        CsGenExporter mapExporter = new CsGenExporter();

        mapExporter.namerFunc = namingFunc;
        mapExporter.atlasSize = outputImage.Width;
        mapExporter.Save(codeFile, outputMap);

        return(200);
    }
Example #14
0
        public void PackingWorks()
        {
            var files = GetSpriteFiles();

            Assert.NotEmpty(files);

            var packer = new ImagePacker();

            packer.PackImage(files, true, true, 4096, 4096, 2, out var image, out var map);

            Assert.NotNull(image);
            Assert.NotNull(map);

            var outFile = new FileInfo("TestOutput.png");

            using (var stream = outFile.Open(FileMode.Create))
            {
                image.Save(stream, new PngEncoder());
            }
        }
        /// <inheritdoc />
        public virtual async Task <Result <IWebhook> > CreateWebhookAsync
        (
            Snowflake channelID,
            string name,
            Optional <Stream?> avatar,
            CancellationToken ct = default
        )
        {
            if (name.Length < 1 || name.Length > 80)
            {
                return(new GenericError("Names must be between 1 and 80 characters"));
            }

            if (name.Equals("clyde", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new GenericError("Names cannot be \"clyde\"."));
            }

            var packAvatar = await ImagePacker.PackImageAsync(avatar, ct);

            if (!packAvatar.IsSuccess)
            {
                return(Result <IWebhook> .FromError(new GenericError("Failed to pack avatar."), packAvatar));
            }

            var avatarData = packAvatar.Entity;

            return(await _discordHttpClient.PostAsync <IWebhook>
                   (
                       $"channels/{channelID}/webhooks",
                       b => b.WithJson
                       (
                           json =>
            {
                json.WriteString("name", name);
                json.WriteString("avatar", avatarData.Value);
            }
                       ),
                       ct : ct
                   ));
        }
Example #16
0
        private void GetImagesRecursively(DirectoryInfo dirPath, string prefix)
        {
            var files = SystemTool.GetDirectoryFiles(dirPath);

            foreach (var file in files)
            {
                if (!file.Name.EndsWith(".png"))
                {
                    Logger.LogInfoLine("{0}Only accept png image:{1}", prefix, file);
                    continue;
                }
                var imageFile = new ImageFile(file, true, true);
                //Logger.LogInfoLine("{0}File:\t{1}", prefix, file.FullName.Replace(PathManager.InputImagesPath.FullName, string.Empty));
                bool isPacked = !file.Directory.FullName.Contains(PathManager.InputImageOtherPath.FullName);

                bool isPVREnabled = false;
                if (PublishTarget.Current.IsPVR)
                {
                    isPVREnabled = mPVREnabledDirectoryNames.Any(pvrEnabledDirectoryName => file.Directory.FullName.Contains(pvrEnabledDirectoryName));
                }
                //bool isEffectAnimation = file.Directory.FullName.Contains("EffectAnimation");
                //isPacked &= !isEffectAnimation;
                //bool isOptimzed = !isEffectAnimation;
                if (!PublishTarget.Current.IsPack)
                {
                    isPacked = false;
                }

                bool isOptimzed = PublishTarget.Current.IsOptimzed;
                bool isPOT      = PublishTarget.Current.IsPOT;
                bool isSquare   = PublishTarget.Current.IsSquare;
                if (isPVREnabled)
                {
                    isPOT    = true;
                    isSquare = true;
                }

                ImagePacker.AddImage(imageFile, PublishTarget.Current, isPacked, isOptimzed, isPVREnabled, isPOT, isSquare);
                FilterImage(file);
            }
        }
Example #17
0
        /// <inheritdoc />
        public virtual async Task <Result <IEmoji> > CreateGuildEmojiAsync
        (
            Snowflake guildID,
            string name,
            Stream image,
            IReadOnlyList <Snowflake> roles,
            CancellationToken ct = default
        )
        {
            if (image.Length > 256000)
            {
                return(new NotSupportedError("Image too large (max 256k)."));
            }

            var packImage = await ImagePacker.PackImageAsync(image, ct);

            if (!packImage.IsSuccess)
            {
                return(Result <IEmoji> .FromError(packImage));
            }

            var emojiData = packImage.Entity;

            return(await this.DiscordHttpClient.PostAsync <IEmoji>
                   (
                       $"guilds/{guildID}/emojis",
                       b => b.WithJson
                       (
                           json =>
            {
                json.WriteString("name", name);
                json.WriteString("image", emojiData);

                json.WritePropertyName("roles");
                JsonSerializer.Serialize(json, roles, this.JsonOptions);
            }
                       ),
                       ct : ct
                   ));
        }
        public void Test02_TextureTest()
        {
            Logfile log = UnitTestHelper.CreateLogfile();

            Assert.IsNotNull(log);
            Assert.IsTrue(log.CanWrite);

            //create objects
            List <Texture> texturelist     = null;
            XmlNodeList    xmlTextureList  = null;
            MapHandler     mapHandler      = new MapHandler();
            ImagePacker    imagePacker     = new ImagePacker();
            XmlDocument    textureDocument = new XmlDocument();

            //setup paths
            string testFileIn = Path.Combine(UnitTestHelper.ResourcesFolder, "battleAtlas.xml");

            Assert.IsTrue(File.Exists(testFileIn));
            string testFileOut = Path.Combine(UnitTestHelper.ResourcesFolder, "battleAtlas2.xml");

            if (File.Exists(testFileOut))
            {
                File.Delete(testFileOut);
            }

            //load sub-texture count to xml
            textureDocument.Load(testFileIn);
            xmlTextureList = textureDocument.SelectNodes("//SubTexture");
            int numSubTextures = xmlTextureList.Count;

            //load texture list
            log.Write("Asserting to load a xml texture file to Texture list");
            texturelist = mapHandler.LoadMapFile(testFileIn);
            log.Write(string.Format("Texture class load status: {0}", texturelist != null));
            Assert.IsNotNull(texturelist);

            //compare texture count
            log.Write(string.Format("Xml node textures: {0}, parsed: {1}", numSubTextures, texturelist.Count));
            Assert.AreEqual(numSubTextures, texturelist.Count);

            //for the packer, need to create bitmaps. we won't use them
            foreach (Texture tex in texturelist)
            {
                tex.AtlasImage = new Bitmap(1, 1);
            }

            //compare each individual texture
            log.Write("Asserting each texture matches from xml to texture list");
            for (int i = 0; i < texturelist.Count; i++)
            {
                Texture    texture    = texturelist[i];
                XmlElement xmlTexture = xmlTextureList[i] as XmlElement;

                //properties match lowercase xml properties names
                foreach (string propertyName in texture.PropertiesForSerializationElements())
                {
                    XmlElement element = xmlTexture.SelectSingleNode(propertyName.ToLower()) as XmlElement;
                    Assert.IsNotNull(element);
                    string xmlValue = element.InnerText.Trim();
                    //for reference
                    //PropertyInfo property = listObjectType.GetProperty(attributeName);
                    PropertyInfo property = typeof(Texture).GetProperty(propertyName);
                    Assert.IsNotNull(property);
                    object value = property.GetValue(texture);
                    Assert.IsNotNull(value);
                    Assert.AreEqual(xmlValue, value.ToString());
                }
            }

            //pack textures
            FailCode code = imagePacker.PackImage(texturelist, true, false, true, 8192, 8192, 1, "battleAtlas.dds", out Bitmap map, out Dictionary <string, Rectangle> imageSizes);

            log.Write(string.Format("Packer fail code: {0}", code.ToString()));
            Assert.AreEqual(FailCode.None, code);

            //for the packer, need to dispose bitmaps
            map.Dispose();
            foreach (Texture tex in texturelist)
            {
                tex.AtlasImage.Dispose();
            }

            //save to new xml file
            mapHandler.SaveMapfile(testFileOut, imageSizes);
            Assert.IsTrue(File.Exists(testFileOut));

            //compare texture count
            textureDocument = new XmlDocument();
            textureDocument.Load(testFileOut);
            xmlTextureList = textureDocument.SelectNodes("//SubTexture");
            numSubTextures = xmlTextureList.Count;
            log.Write(string.Format("Xml node textures: {0}, parsed: {1}", numSubTextures, imageSizes.Count));
            Assert.AreEqual(numSubTextures, imageSizes.Count);

            //compare each individual texture
            log.Write("Asserting each texture matches from xml to dictionary");
            for (int i = 0; i < xmlTextureList.Count; i++)
            {
                XmlElement xmlTexture = xmlTextureList[i] as XmlElement;
                Assert.IsNotNull(xmlTexture);
                string    textureName = xmlTexture.SelectSingleNode(nameof(Texture.Name).ToLower()).InnerText.Trim();
                Rectangle imageSize   = imageSizes[textureName];
                Assert.IsNotNull(imageSize);

                string[] propertiesToCheck = { nameof(imageSize.X), nameof(imageSize.Y), nameof(imageSize.Width), nameof(imageSize.Height) };
                foreach (string propertyName in propertiesToCheck)
                {
                    XmlElement xmlProperty = xmlTexture.SelectSingleNode(propertyName.ToLower()) as XmlElement;
                    Assert.IsNotNull(xmlProperty);

                    PropertyInfo property = imageSize.GetType().GetProperty(propertyName);
                    Assert.IsNotNull(property);
                    object propertyValue = property.GetValue(imageSize);
                    Assert.IsNotNull(propertyValue);
                    Assert.IsTrue(propertyValue is int);

                    Assert.AreEqual(xmlProperty.InnerText.Trim(), propertyValue.ToString());
                }
            }

            File.Delete(testFileOut);

            UnitTestHelper.DestroyLogfile(ref log, false);
            Assert.IsNull(log);
        }
Example #19
0
        public void PackWithBufferMosiacTests(RectInt[] rects, int padding, Vector2Int expectedSize)
        {
            RectInt[] packedRect;
            int       packedWidth, packedHeight;

            // Find the largest buffer
            int maxWidth = -1, maxHeight = -1;

            for (int i = 0; i < rects.Length; ++i)
            {
                if (rects[i].width > maxWidth)
                {
                    maxWidth = rects[i].width;
                }
                if (rects[i].height > maxHeight)
                {
                    maxHeight = rects[i].height;
                }
            }

            // Setup color buffers
            NativeArray <Color32>[] buffers = new NativeArray <Color32> [rects.Length];
            for (int i = 0; i < rects.Length; ++i)
            {
                buffers[i] = new NativeArray <Color32>(maxWidth * maxHeight, Allocator.Temp);
                for (int j = 0; j < maxHeight; ++j)
                {
                    for (int k = 0; k < maxWidth; ++k)
                    {
                        int bufferIndex = (j * maxWidth + k);
                        if (k >= rects[i].width || j >= rects[i].height)
                        {
                            buffers[i][bufferIndex] = new Color32(0, 0, 0, 0);
                        }
                        else
                        {
                            buffers[i][bufferIndex] = new Color32((byte)i, (byte)i, (byte)i, 255);
                        }
                    }
                }
            }

            NativeArray <Color32> packedBuffer;

            Vector2Int[] uvTransform;
            ImagePacker.Pack(buffers, maxWidth, maxHeight, padding, out packedBuffer, out packedWidth, out packedHeight, out packedRect, out uvTransform);
            Assert.AreEqual(expectedSize.x, packedWidth);
            Assert.AreEqual(expectedSize.y, packedHeight);
            Assert.AreEqual(rects.Length, packedRect.Length);

            // Ensure all rects exists
            int bytesPerRow = packedWidth;

            for (int i = 0; i < packedRect.Length; ++i)
            {
                // Ensure rect doesn't overlap with other rects
                RectInt testRect = packedRect[i];
                for (int k = i + 1; k < packedRect.Length; ++k)
                {
                    RectInt other    = packedRect[k];
                    var     contains = !((other.xMax + padding <= testRect.xMin ||
                                          other.yMax + padding <= testRect.yMin) ||
                                         (other.xMin >= testRect.xMax + padding ||
                                          other.yMin >= testRect.yMax + padding));
                    Assert.IsFalse(contains);
                }

                // Ensure rects has the correct padding
                Assert.AreEqual(rects[i].width, testRect.width);
                Assert.AreEqual(rects[i].height, testRect.height);

                // Ensure buffers are blitted to the correct place. We will just sample min, max and center point
                if (testRect.width > 0 && testRect.height > 0)
                {
                    Assert.IsTrue(PixelColorEqual(packedBuffer, packedWidth, bytesPerRow, testRect.xMin + padding, testRect.yMin, new Color32((byte)i, (byte)i, (byte)i, 255)));
                    Assert.IsTrue(PixelColorEqual(packedBuffer, packedWidth, bytesPerRow, testRect.xMax - 1, testRect.yMax - 1, new Color32((byte)i, (byte)i, (byte)i, 255)));
                    Assert.IsTrue(PixelColorEqual(packedBuffer, packedWidth, bytesPerRow, (int)testRect.center.x - 1, (int)testRect.center.y - 1, new Color32((byte)i, (byte)i, (byte)i, 255)));
                }
            }

            packedBuffer.Dispose();
            for (int i = 0; i < buffers.Length; ++i)
            {
                buffers[i].Dispose();
            }
        }
Example #20
0
 public int NextPowerOfTwoTest(int value)
 {
     return((int)ImagePacker.NextPowerOfTwo((ulong)value));
 }
Example #21
0
        public static int Main(string[] args)
        {
            var app             = new CommandLineApplication(false);
            var folderOption    = app.Option("-f | --folder", "Specifies input folder", CommandOptionType.SingleValue);
            var outputOption    = app.Option("-o | --output", "Specifies the output image's file name", CommandOptionType.SingleValue);
            var mapOption       = app.Option("-m | --map", "Specifies the map's file name", CommandOptionType.SingleValue);
            var powTwoOption    = app.Option("-2 | --pow2", "Forces that the output to have power of two dimensions", CommandOptionType.NoValue);
            var squareOption    = app.Option("-s | --square", "Forces that the output to be have equal width and length", CommandOptionType.NoValue);
            var maxWidthOption  = app.Option("-w | --maxwidth", "Specifies the maximum allowed output width", CommandOptionType.SingleValue);
            var maxHeightOption = app.Option("-h | --maxwidth", "Specifies the maximum allowed output height", CommandOptionType.SingleValue);
            var paddingOption   = app.Option("-p | --padding", "Specifies the padding in pixel between packed subimages", CommandOptionType.SingleValue);

            app.HelpOption("-? | -h | --help");
            app.OnExecute(() =>
            {
                if (!folderOption.HasValue() || !outputOption.HasValue())
                {
                    Console.WriteLine("An input folder and an output filename are required");
                    return(1);
                }

                var inputDir   = new DirectoryInfo(folderOption.Value());
                var inputFiles = inputDir.GetFiles().Where(d => ImagePacker.SupportedImageExtensions.Contains(d.Extension.ToLower())).ToArray();
                if (!inputFiles.Any())
                {
                    Console.WriteLine("No supported files found");
                    return(1);
                }

                var outFile    = new FileInfo(outputOption.Value());
                var outEncoder = ImagePacker.GetEncoderFromExtension(outFile.Extension);
                if (outEncoder == null)
                {
                    Console.WriteLine("Unsupported output file format");
                    return(1);
                }

                var outMap = mapOption.HasValue() ? new FileInfo(mapOption.Value()) : null;
                IMapGenerator outGenerator = null;
                if (outMap != null)
                {
                    outGenerator = MapGenerators.FirstOrDefault(d => d.MapExtension == outMap.Extension.ToLower());
                    if (outGenerator == null)
                    {
                        Console.WriteLine("Unsupported output map format");
                        return(1);
                    }
                }

                var valueParsed = int.TryParse(maxWidthOption.Value(), out var maxWidth);
                if (!valueParsed)
                {
                    maxWidth = DefaultSize;
                }
                valueParsed = int.TryParse(maxHeightOption.Value(), out var maxHeight);
                if (!valueParsed)
                {
                    maxHeight = DefaultSize;
                }
                valueParsed = int.TryParse(paddingOption.Value(), out var padding);
                if (!valueParsed)
                {
                    padding = DefaultPadding;
                }

                var packer = new ImagePacker();
                packer.PackImage(inputFiles, powTwoOption.HasValue(), squareOption.HasValue(), maxWidth, maxHeight, padding, out var packedImage, out var packedMap);

                using (var outStream = outFile.Open(FileMode.Create))
                {
                    packedImage.Save(outStream, outEncoder);
                }

                if (outGenerator != null)
                {
                    var mapBytes = outGenerator.Generate(packedMap);
                    using (var outStream = outMap.Open(FileMode.Create))
                    {
                        outStream.Write(mapBytes, 0, mapBytes.Length);
                    }
                }

                return(0);
            });

            return(app.Execute(args));
        }
Example #22
0
        public void PostCheck()
        {
            CheckUsage();

            ImagePacker.Pack(PublishTarget.Current);
        }
Example #23
0
        /// <inheritdoc />
        public virtual async Task <Result <IGuild> > ModifyGuildAsync
        (
            Snowflake guildID,
            Optional <string> name    = default,
            Optional <string?> region = default,
            Optional <VerificationLevel?> verificationLevel = default,
            Optional <MessageNotificationLevel?> defaultMessageNotifications = default,
            Optional <ExplicitContentFilterLevel?> explicitContentFilter     = default,
            Optional <Snowflake?> afkChannelID                = default,
            Optional <TimeSpan> afkTimeout                    = default,
            Optional <Stream?> icon                           = default,
            Optional <Snowflake> ownerID                      = default,
            Optional <Stream?> splash                         = default,
            Optional <Stream?> discoverySplash                = default,
            Optional <Stream?> banner                         = default,
            Optional <Snowflake?> systemChannelID             = default,
            Optional <SystemChannelFlags> systemChannelFlags  = default,
            Optional <Snowflake?> rulesChannelID              = default,
            Optional <Snowflake?> publicUpdatesChannelID      = default,
            Optional <string?> preferredLocale                = default,
            Optional <IReadOnlyList <GuildFeature> > features = default,
            Optional <string?> description                    = default,
            CancellationToken ct = default
        )
        {
            await using var memoryStream = new MemoryStream();

            Optional <string?> iconData = default;

            if (icon.HasValue)
            {
                if (icon.Value is null)
                {
                    iconData = new Optional <string?>(null);
                }
                else
                {
                    var packImage = await ImagePacker.PackImageAsync(icon.Value, ct);

                    if (!packImage.IsSuccess)
                    {
                        return(Result <IGuild> .FromError(new GenericError("Failed to pack icon."), packImage));
                    }

                    iconData = packImage.Entity;
                }
            }

            Optional <string?> splashData = default;

            if (splash.HasValue)
            {
                if (splash.Value is null)
                {
                    splashData = new Optional <string?>(null);
                }
                else
                {
                    var packImage = await ImagePacker.PackImageAsync(splash.Value, ct);

                    if (!packImage.IsSuccess)
                    {
                        return(Result <IGuild> .FromError(new GenericError("Failed to pack splash."), packImage));
                    }

                    splashData = packImage.Entity;
                }
            }

            Optional <string?> discoverySplashData = default;

            if (discoverySplash.HasValue)
            {
                if (discoverySplash.Value is null)
                {
                    discoverySplashData = new Optional <string?>(null);
                }
                else
                {
                    var packImage = await ImagePacker.PackImageAsync(discoverySplash.Value, ct);

                    if (!packImage.IsSuccess)
                    {
                        return(Result <IGuild> .FromError(new GenericError("Failed to pack discovery splash."), packImage));
                    }

                    discoverySplashData = packImage.Entity;
                }
            }

            var packBanner = await ImagePacker.PackImageAsync(banner, ct);

            if (!packBanner.IsSuccess)
            {
                return(Result <IGuild> .FromError(new GenericError("Failed to pack banner."), packBanner));
            }

            var bannerData = packBanner.Entity;

            return(await _discordHttpClient.PatchAsync <IGuild>
                   (
                       $"guilds/{guildID}",
                       b => b.WithJson
                       (
                           json =>
            {
                json.Write("name", name, _jsonOptions);
                json.Write("region", region, _jsonOptions);
                json.WriteEnum("verification_level", verificationLevel, jsonOptions: _jsonOptions);
                json.WriteEnum
                (
                    "default_message_notifications",
                    defaultMessageNotifications,
                    jsonOptions: _jsonOptions
                );

                json.WriteEnum("explicit_content_filter", explicitContentFilter, jsonOptions: _jsonOptions);
                json.Write("afk_channel_id", afkChannelID, _jsonOptions);

                if (afkTimeout.HasValue)
                {
                    json.WriteNumber("afk_timeout", (ulong)afkTimeout.Value.TotalSeconds);
                }

                json.Write("icon", iconData, _jsonOptions);
                json.Write("owner_id", ownerID, _jsonOptions);
                json.Write("splash", splashData, _jsonOptions);
                json.Write("discovery_splash", discoverySplashData, _jsonOptions);
                json.Write("banner", bannerData, _jsonOptions);
                json.Write("system_channel_id", systemChannelID, _jsonOptions);
                json.Write("system_channel_flags", systemChannelFlags, _jsonOptions);
                json.Write("rules_channel_id", rulesChannelID, _jsonOptions);
                json.Write("public_updates_channel_id", publicUpdatesChannelID, _jsonOptions);
                json.Write("preferred_locale", preferredLocale, _jsonOptions);
                json.Write("features", features, _jsonOptions);
                json.Write("description", description, _jsonOptions);
            }
                       ),
                       ct : ct
                   ));
        }
Example #24
0
        void PackOnce()
        {
            if (mPackTasks.Count == 0)
            {
                return;
            }
            // generate our output
            ImagePacker imagePacker = new ImagePacker();
            Bitmap      outputImage;
            Dictionary <string, System.Drawing.Rectangle> outputMap;
            PackTask pt = mPackTasks.Dequeue();

            Console.WriteLine("Packing {0} ({1} left to pack)", pt.outputFile, mPackTasks.Count);

            // pack the image, generating a map only if desired
            int result = imagePacker.PackImage(pt.inputFiles, REQUIRE_POW2, REQUIRE_SQUARE, 4096, 4096, PADDING, true, out outputImage, out outputMap);

            if (result != 0)
            {
                Console.WriteLine("There was an error making the image sheet.");
                return;
            }

            // try to save using our exporters
            try
            {
                if (File.Exists(pt.outputFile))
                {
                    File.Delete(pt.outputFile);
                }
                mImageExporter.Save(pt.outputFile, outputImage);
                Console.WriteLine("Saved atlas {0}.", pt.outputFile);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error saving file: " + e.Message);
                return;
            }

            if (mMapExporter != null)
            {
                try
                {
                    if (File.Exists(pt.outputMap))
                    {
                        File.Delete(pt.outputMap);
                    }
                    mMapExporter.Save(pt.outputMap, outputMap);
                    Console.WriteLine("Saved atlas map {0}.", pt.outputMap);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error saving file: " + e.Message);
                    return;
                }
            }
            foreach (string filename in pt.inputFiles)
            {
                if (File.Exists(filename))
                {
                    try
                    {
                        File.Delete(filename);
                    }
                    catch (IOException)
                    {
                        // Welp
                    }
                }
            }
        }
Example #25
0
        void ImportFromLayers(AssetImportContext ctx, Document doc)
        {
            NativeArray <Color32> output = default(NativeArray <Color32>);

            List <int> layerIndex     = new List <int>();
            List <int> spriteNameHash = new List <int>();
            var        oldPsdLayers   = GetPSDLayers();

            try
            {
                var psdLayers = new List <PSDLayer>();
                ExtractLayerTask.Execute(psdLayers, doc.Layers, m_ImportHiddenLayers);
                var removedLayersSprite = oldPsdLayers.Where(x => psdLayers.FirstOrDefault(y => y.layerID == x.layerID) == null).Select(z => z.spriteID).ToArray();
                for (int i = 0; i < psdLayers.Count; ++i)
                {
                    int j        = 0;
                    var psdLayer = psdLayers[i];
                    for (; j < oldPsdLayers.Count; ++j)
                    {
                        if (psdLayer.layerID == oldPsdLayers[j].layerID)
                        {
                            psdLayer.spriteID       = oldPsdLayers[j].spriteID;
                            psdLayer.spriteName     = oldPsdLayers[j].spriteName;
                            psdLayer.mosaicPosition = oldPsdLayers[j].mosaicPosition;
                            break;
                        }
                    }
                }

                int expectedBufferLength = doc.width * doc.height;
                var layerBuffers         = new List <NativeArray <Color32> >();
                for (int i = 0; i < psdLayers.Count; ++i)
                {
                    var l = psdLayers[i];
                    if (l.texture.IsCreated && l.texture.Length == expectedBufferLength)
                    {
                        layerBuffers.Add(l.texture);
                        layerIndex.Add(i);
                    }
                }

                RectInt[]    spritedata;
                int          width, height;
                int          padding = 4;
                Vector2Int[] uvTransform;
                ImagePacker.Pack(layerBuffers.ToArray(), doc.width, doc.height, padding, out output, out width, out height, out spritedata, out uvTransform);
                var spriteImportData = GetSpriteImportData();
                if (spriteImportData.Count <= 0 || shouldResliceFromLayer)
                {
                    var newSpriteMeta = new List <SpriteMetaData>();

                    for (int i = 0; i < spritedata.Length && i < layerIndex.Count; ++i)
                    {
                        var spriteSheet = spriteImportData.FirstOrDefault(x => x.spriteID == psdLayers[layerIndex[i]].spriteID);
                        if (spriteSheet == null)
                        {
                            spriteSheet           = new SpriteMetaData();
                            spriteSheet.border    = Vector4.zero;
                            spriteSheet.alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
                            spriteSheet.pivot     = m_TextureImporterSettings.spritePivot;
                        }

                        psdLayers[layerIndex[i]].spriteName = GetUniqueName(psdLayers[layerIndex[i]].name, spriteNameHash);
                        spriteSheet.name        = psdLayers[layerIndex[i]].spriteName;
                        spriteSheet.rect        = new Rect(spritedata[i].x, spritedata[i].y, spritedata[i].width, spritedata[i].height);
                        spriteSheet.uvTransform = uvTransform[i];

                        psdLayers[layerIndex[i]].spriteID       = spriteSheet.spriteID;
                        psdLayers[layerIndex[i]].mosaicPosition = spritedata[i].position;
                        newSpriteMeta.Add(spriteSheet);
                    }
                    spriteImportData.Clear();
                    spriteImportData.AddRange(newSpriteMeta);
                }
                else
                {
                    spriteImportData.RemoveAll(x => removedLayersSprite.Contains(x.spriteID));

                    foreach (var spriteData in spriteImportData)
                    {
                        var psdLayer = psdLayers.FirstOrDefault(x => x.spriteID == spriteData.spriteID);
                        if (psdLayer == null)
                        {
                            spriteData.uvTransform = new Vector2Int((int)spriteData.rect.position.x, (int)spriteData.rect.position.y);
                        }
                        // If it is user created rect or the name has been changed before
                        // add it into the spriteNameHash and we don't copy it over from the layer
                        if (psdLayer == null || psdLayer.spriteName != spriteData.name)
                        {
                            spriteNameHash.Add(spriteData.name.GetHashCode());
                        }

                        // If the sprite name has not been changed, we ensure the new
                        // layer name is still unique and use it as the sprite name
                        if (psdLayer != null && psdLayer.spriteName == spriteData.name)
                        {
                            psdLayer.spriteName = GetUniqueName(psdLayer.name, spriteNameHash);
                            spriteData.name     = psdLayer.spriteName;
                        }
                    }

                    //Update names for those user has not changed and add new sprite rect based on PSD file.
                    for (int k = 0; k < layerIndex.Count; ++k)
                    {
                        int i           = layerIndex[k];
                        var spriteSheet = spriteImportData.FirstOrDefault(x => x.spriteID == psdLayers[i].spriteID);
                        var inOldLayer  = oldPsdLayers.FindIndex(x => x.layerID == psdLayers[i].layerID) != -1;
                        if (spriteSheet == null && !inOldLayer)
                        {
                            spriteSheet = new SpriteMetaData();
                            spriteImportData.Add(spriteSheet);
                            spriteSheet.rect        = new Rect(spritedata[k].x, spritedata[k].y, spritedata[k].width, spritedata[k].height);
                            spriteSheet.border      = Vector4.zero;
                            spriteSheet.alignment   = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
                            spriteSheet.pivot       = m_TextureImporterSettings.spritePivot;
                            psdLayers[i].spriteName = GetUniqueName(psdLayers[i].name, spriteNameHash);
                            spriteSheet.name        = psdLayers[i].spriteName;
                        }
                        else if (spriteSheet != null)
                        {
                            var r = spriteSheet.rect;
                            r.position       = spriteSheet.rect.position - psdLayers[i].mosaicPosition + spritedata[k].position;
                            spriteSheet.rect = r;
                        }

                        if (spriteSheet != null)
                        {
                            spriteSheet.uvTransform     = uvTransform[k];
                            psdLayers[i].spriteID       = spriteSheet.spriteID;
                            psdLayers[i].mosaicPosition = spritedata[k].position;
                        }
                    }
                }
                oldPsdLayers.Clear();
                oldPsdLayers.AddRange(psdLayers);
                m_ResliceFromLayer      = false;
                m_ImportedTextureHeight = textureActualHeight = height;
                m_ImportedTextureWidth  = textureActualWidth = width;
                var generatedTexture = ImportTexture(ctx, output, width, height, 0, spriteImportData.Count);
                m_ImportedTextureHeight = generatedTexture.texture.height;
                m_ImportedTextureWidth  = generatedTexture.texture.width;
                RegisterAssets(ctx, generatedTexture);
            }
            finally
            {
                if (output.IsCreated)
                {
                    output.Dispose();
                }
                foreach (var l in oldPsdLayers)
                {
                    l.Dispose();
                }
            }
        }