{"action":"created","issue":{"url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/issues/322","repository_url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor","labels_url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/issues/322/labels{/name}","comments_url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/issues/322/comments","events_url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/issues/322/events","html_url":"https://github.com/JimBobSquarePants/ImageProcessor/pull/322","id":131066206,"number":322,"title":"OutOfMemory exception processing animated GIF #308","user":{"login":"nul800sebastiaan","id":304656,"avatar_url":"https://avatars.githubusercontent.com/u/304656?v=3","gravatar_id":"","url":"https://api.github.com/users/nul800sebastiaan","html_url":"https://github.com/nul800sebastiaan","followers_url":"https://api.github.com/users/nul800sebastiaan/followers","following_url":"https://api.github.com/users/nul800sebastiaan/following{/other_user}","gists_url":"https://api.github.com/users/nul800sebastiaan/gists{/gist_id}","starred_url":"https://api.github.com/users/nul800sebastiaan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nul800sebastiaan/subscriptions","organizations_url":"https://api.github.com/users/nul800sebastiaan/orgs","repos_url":"https://api.github.com/users/nul800sebastiaan/repos","events_url":"https://api.github.com/users/nul800sebastiaan/events{/privacy}","received_events_url":"https://api.github.com/users/nul800sebastiaan/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-02-03T15:54:44Z","updated_at":"2016-02-03T22:57:18Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/pulls/322","html_url":"https://github.com/JimBobSquarePants/ImageProcessor/pull/322","diff_url":"https://github.com/JimBobSquarePants/ImageProcessor/pull/322.diff","patch_url":"https://github.com/JimBobSquarePants/ImageProcessor/pull/322.patch"},"body":"Learned some stuff about the code and noticed that what's handled in `GifDecoder` gets sent to `ImageExtensions.Copy`, sweet! So only need to update code in one place (I should've known).\r\n\r\nSo, this is just starting the conversation and explains a bit of what I've tried:\r\n- I tried taking 10 frames from that giant 694 frame GIF and making an animation out of that with disastrous results (so this took frame number 0, 69, 69x2, 69x3, etc until 69x10 and mashed them together): \r\n  \r\n![ogb-insider-blogs-googlelogox2-animated 1](https://cloud.githubusercontent.com/assets/304656/12787256/ec1f3c94-ca94-11e5-9149-c78f53133cfb.gif)\r\n- I don't think processing many more than 10 frames is a very good idea, if there's many gifs, it will be rough on CPU/memory. \r\n- Decided to stick with just showing the first frame\r\n  - This is currently hardcoded but needs to be configurable from querystring (please advise, not sure how to get the variable in the `GifDecoder`)\r\n- The code is currently doing: \r\n\r\n```\r\n                        // Reset the position.\r\n                        if (i == last)\r\n                        {\r\n                            image.SelectActiveFrame(FrameDimension.Time, 0);\r\n                        }\r\n```\r\n\r\nI don't know what this achieves, but if this is required to run then I need to fix it here for when there's only one frame processed (please advise)."},"comment":{"url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/issues/comments/179517687","html_url":"https://github.com/JimBobSquarePants/ImageProcessor/pull/322#issuecomment-179517687","issue_url":"https://api.github.com/repos/JimBobSquarePants/ImageProcessor/issues/322","id":179517687,"user":{"login":"JimBobSquarePants","id":385879,"avatar_url":"https://avatars.githubusercontent.com/u/385879?v=3","gravatar_id":"","url":"https://api.github.com/users/JimBobSquarePants","html_url":"https://github.com/JimBobSquarePants","followers_url":"https://api.github.com/users/JimBobSquarePants/followers","following_url":"https://api.github.com/users/JimBobSquarePants/following{/other_user}","gists_url":"https://api.github.com/users/JimBobSquarePants/gists{/gist_id}","starred_url":"https://api.github.com/users/JimBobSquarePants/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JimBobSquarePants/subscriptions","organizations_url":"https://api.github.com/users/JimBobSquarePants/orgs","repos_url":"https://api.github.com/users/JimBobSquarePants/repos","events_url":"https://api.github.com/users/JimBobSquarePants/events{/privacy}","received_events_url":"https://api.github.com/users/JimBobSquarePants/received_events","type":"User","site_admin":false},"created_at":"2016-02-03T22:57:18Z","updated_at":"2016-02-03T22:57:18Z","body":"Good to see progress made chum!\r\n\r\nI think we'd have to add an interface to the `GifFormat` containing the `AnimationProcessMode` enum, `IAnimatedImageFormat`. Doing that should allow us to check for the interface and assign the value by adding the same enum as a property on the `ImageFactory` class. By adding the interface we can keep a minor version also since we are not adding a property to `ISupportedImageFormat`\r\n\r\nIn the `ImageFactory.Load()` variants \r\n\r\n``` c#\r\nif (this.CurrentImageFormat is IAnimatedImageFormat){\r\n    ((IAnimatedImageFormat)this.CurrentImageFormat).AnimationProcessMode = this.AnimationProcessMode;\r\n}\r\n```\r\n\r\nIn the HttpModule in ImageProcessor.Web we could detect the querystring value using the `QueryParamParser` which can handle enums.  Using that you could set the factory property. It would have to be done separately from any standard `IWebGraphicsProcessor` since it needs to happen on initialization. You want to do something like.\r\n\r\n``` c#\r\nAnimationProcessMode mode = this.ParseAnimationMode(queryString);\r\n\r\nusing (ImageFactory imageFactory = new ImageFactory(exif, gamma){ AnimationProcessMode = mode })\r\n{\r\n    // Do the normal stuff\r\n}\r\n```\r\n\r\nAs for this bit of code:\r\n\r\n``` c#\r\n // Reset the position.\r\nif (i == last)\r\n{\r\n    image.SelectActiveFrame(FrameDimension.Time, 0);\r\n}\r\n```\r\n\r\nThat resets the animated image so that we are reading from the correct first frame when performing additional processing. \r\n\r\nDoes that make sense to you?"}}