From 0ac9487e8400e6a3f933085b00e338b7f20e888b Mon Sep 17 00:00:00 2001 From: esn303 Date: Sun, 10 Mar 2013 14:36:54 +0100 Subject: [PATCH] Added attribute to define default preset for fallback images --- plugin/FilterModule/MarkupParser.cs | 88 +++++++++++++++-------------- readme.md | 2 +- www/ImageResizer.config | 19 ++++--- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/plugin/FilterModule/MarkupParser.cs b/plugin/FilterModule/MarkupParser.cs index a170eb7..2824b81 100644 --- a/plugin/FilterModule/MarkupParser.cs +++ b/plugin/FilterModule/MarkupParser.cs @@ -31,64 +31,66 @@ public string TransformImgToPicture(string content) foreach (HtmlNode img in doc.DocumentNode.SelectNodes("//img[@src]")) { HtmlAttribute src = img.Attributes["src"]; - if (src != null) + if (src != null && src.Value.ToLowerInvariant().IndexOf("preset=.") != -1) { - if (src.Value.ToLowerInvariant().IndexOf("preset=.") != -1) - { - HtmlNode fallbackImg = img.Clone(); + HtmlNode fallbackImg = img.Clone(); + + // - make this "img" a "picture" + img.Name = "picture"; - // - make this "img" a "picture" - img.Name = "picture"; + // - get presets from config + var configSection = WebConfigurationManager.GetSection("resizer") as ImageResizer.ResizerSection; + XmlElement conf = configSection.getCopyOfNode("responsivepresets").ToXmlElement(); + XmlNode defaultPrefix = conf.SelectSingleNode("preset[@default='true']/@prefix"); - // - get presets from config - var configSection = WebConfigurationManager.GetSection("resizer") as ImageResizer.ResizerSection; - XmlElement conf = configSection.getCopyOfNode("responsivepresets").ToXmlElement(); + // - set default preset as fallback image + if (defaultPrefix != null) + fallbackImg.Attributes["src"].Value = fallbackImg.Attributes["src"].Value.Replace("preset=.", "preset=" + defaultPrefix.Value + "."); - // - filter configuration - bool respectPixelDensity = (conf.Attributes["respectPixelDensity"].Value == "true"); + // - filter configuration + bool respectPixelDensity = (conf.Attributes["respectPixelDensity"].Value == "true"); - // - add "source" tag for each preset item - if (conf.ChildNodes != null && conf.HasChildNodes) + // - add "source" tag for each preset item + if (conf.ChildNodes != null && conf.HasChildNodes) + { + foreach (XmlNode c in conf.ChildNodes) { - foreach (XmlNode c in conf.ChildNodes) + string name = c.Attributes["prefix"].Value; + if (c.Name.Equals("preset", StringComparison.OrdinalIgnoreCase)) { - string name = c.Attributes["prefix"].Value; - if (c.Name.Equals("preset", StringComparison.OrdinalIgnoreCase)) - { - HtmlNode source = doc.CreateElement("source"); - if (c.Attributes["media"]!=null) - source.Attributes.Add("media", c.Attributes["media"].Value); + HtmlNode source = doc.CreateElement("source"); + if (c.Attributes["media"]!=null) + source.Attributes.Add("media", c.Attributes["media"].Value); - string srcsetBase = img.Attributes["src"].Value.Replace("preset=.", "preset=" + name + "."); - // - generate x1, x2, x3, x4 (for now ...) if requested to do so - if (respectPixelDensity) - { - StringBuilder srcset = new StringBuilder(); - for (int i = 1; i <= 4; i++) - { - srcset.Append(srcsetBase + "&zoom=" + i + " " + i + "x, "); - } - source.Attributes.Add("srcset", srcset.ToString().Trim().TrimEnd(',')); - } - else + string srcsetBase = img.Attributes["src"].Value.Replace("preset=.", "preset=" + name + "."); + // - generate x1, x2, x3, x4 (for now ...) if requested to do so + if (respectPixelDensity) + { + StringBuilder srcset = new StringBuilder(); + for (int i = 1; i <= 4; i++) { - source.Attributes.Add("src", srcsetBase.ToString().Trim()); + srcset.Append(srcsetBase + "&zoom=" + i + " " + i + "x, "); } - - // - add this "source" tag as a new "img" child - img.ChildNodes.Add(source); + source.Attributes.Add("srcset", srcset.ToString().Trim().TrimEnd(',')); + } + else + { + source.Attributes.Add("src", srcsetBase.ToString().Trim()); } + + // - add this "source" tag as a new "img" child + img.ChildNodes.Add(source); } } + } - // - remove "src" from "picture" (leftover from this being a "img" tag) - img.Attributes.Remove("src"); + // - remove "src" from "picture" (leftover from this being a "img" tag) + img.Attributes.Remove("src"); - // - append fallback image - HtmlNode fallbackContainer = doc.CreateElement("noscript"); - fallbackContainer.AppendChild(fallbackImg); - img.AppendChild(fallbackContainer); - } + // - append fallback image + HtmlNode fallbackContainer = doc.CreateElement("noscript"); + fallbackContainer.AppendChild(fallbackImg); + img.AppendChild(fallbackContainer); } } diff --git a/readme.md b/readme.md index 8af79d8..3d79a7a 100644 --- a/readme.md +++ b/readme.md @@ -1 +1 @@ -# ResponsivePresets for ImageResizer.Net **Effortless reponsive images powered by ImageResizer.Net** ##Introduction Licensed under the [MIT Licence](http://www.opensource.org/licenses/mit-license.php), which allows open source as well as commercial use. ###What does it to? * Converts image tags using [ImageResizer presets](http://imageresizing.net/plugins/presets) to picture tags (as currently proposed by the [Responsive Images Community Group](http://www.w3.org/community/respimg/). * Varies [ImageResizer preset names](http://imageresizing.net/plugins/presets) by media-queries and device pixel ratio for automatic image resizing according to responsive webdesign practices. ### Requirements * ASP.Net 4.0 * [ImageResizer.Net](www.imageresizing.net) 3.1.5+ by Nathanael Jones * [picturefill.js](https://github.com/Wilto/picturefill-proposal) by Mat Marquis (a polyfill for proposed behavior of the picture element) ### Spin it up quickly for a test! * Use WebMatrix and fire it up on the "www"-folder, that's all! ---- ## How to use ResponsivePresets extends the presets that are available with ImageResizer. **With a simple dot-notation (of the preset name), you can enable screen resolution aware dynamic resizing for some - or all - of your images.** **Tipp** >You can run the www-folder in WebMatrix right after cloning the repo, as the assembly binaries are included for easy testing. ### 1. Enable ResponsivePresets ResponsivePresets works in team with the standard Presets plugin for ImageResizer, so you need to enable and configure that as well. Deploy the assembly and activate the plugin: * Copy ResponsivePresets.dll to /bin/ * Copy HtmlAgilityPack.dll to /bin/ Install the HttpModule that activates the request filter which transforms img tags with an dot-notation preset to full blown picture elements in ``, ``: ```xml ``` For a working example see web.config and ImageResizer.config in /www/ ### 2. Segment device screen resolutions The concept for ResponsivePresets is to group screen resolutions in classes that get prefixed to the base preset name. ```xml ``` **Tipp: px or em?** > If you want to also generate image variants optimized for hires-displays (like 4k, or at least "Retina"), it's advisable to use _em_ units and not _px_ units in your media queries. Define which prefix will be used for which range of the screen width. The list is processed top to bottom, first match wins. These values do **not** resize images to these widths, but segment the devices by their available screen width. You are free to segment and structure to your liking, this allows ResponsivePresets to adapt to almost any requirement. ### 3. Configure presets Add a preset to your config, like you would normally do for the presets plugin: ```xml ``` If this setting is i.e. for standard desktop devices, prefix the preset name with *desktop.* like so: ```xml ``` Add presets for all the other prefixes (device segments) ```xml ``` ### 4. Enable "respectPixelDensity"-Setting If set to "true", ResponsivePresets will generate srcset values with 1x, 2x, 3x and 4x variants of the images by [zooming](http://imageresizing.net/docs/reference) the images accordingly. ### 5. Prepare your markup * Reference the (minified) [polyfill javascript](https://github.com/Wilto/picturefill-proposal): ```html ``` * If the pull request with my fix is not already merged, [use this corrected version of the polyfill](https://github.com/Wilto/picturefill-proposal/pull/2): * Adjust image source attribute: Instead of adding a fixed preset name to the image's request string, write the base preset name and prepend a dot to indicate you want this image to be extended by ResponsivePresets: ```html sample image ``` ---- ##Notes Your stylesheet has to take care to resize the images to the desired dimensions, they now greatly vary depending on the client's screen resolution and pixel density. Consider to also include [matchMedia](https://github.com/paulirish/matchMedia.js/). Have a look at the [picturefill compatibility chart](https://github.com/Wilto/picturefill-proposal#support). ---- ## Limitations #### Polyfill vs. browser implementation >While polyfilling does work, using it in real world sites before a major browser implements the picture tag has to be well-considered. ---- Follow [esn303](https://twitter.com/#!/esn303) on twitter This project is open to collaboration. **Fork. Push. Innovate.** \ No newline at end of file +# ResponsivePresets for ImageResizer.Net **Effortless reponsive images powered by ImageResizer.Net** ##Introduction Licensed under the [MIT Licence](http://www.opensource.org/licenses/mit-license.php), which allows open source as well as commercial use. ###What does it to? * Converts image tags using [ImageResizer presets](http://imageresizing.net/plugins/presets) to picture tags (as currently proposed by the [Responsive Images Community Group](http://www.w3.org/community/respimg/). * Varies [ImageResizer preset names](http://imageresizing.net/plugins/presets) by media-queries and device pixel ratio for automatic image resizing according to responsive webdesign practices. ### Requirements * ASP.Net 4.0 * [ImageResizer.Net](www.imageresizing.net) 3.1.5+ by Nathanael Jones * [picturefill.js](https://github.com/Wilto/picturefill-proposal) by Mat Marquis (a polyfill for proposed behavior of the picture element) ### Spin it up quickly for a test! * Use WebMatrix and fire it up on the "www"-folder, that's all! ---- ## How to use ResponsivePresets extends the presets that are available with ImageResizer. **With a simple dot-notation (of the preset name), you can enable screen resolution aware dynamic resizing for some - or all - of your images.** **Tipp** >You can run the www-folder in WebMatrix right after cloning the repo, as the assembly binaries are included for easy testing. ### 1. Enable ResponsivePresets ResponsivePresets works in team with the standard Presets plugin for ImageResizer, so you need to enable and configure that as well. Deploy the assembly and activate the plugin: * Copy ResponsivePresets.dll to /bin/ * Copy HtmlAgilityPack.dll to /bin/ Install the HttpModule that activates the request filter which transforms img tags with an dot-notation preset to full blown picture elements in ``, ``: ```xml ``` For a working example see web.config and ImageResizer.config in /www/ ### 2. Segment device screen resolutions The concept for ResponsivePresets is to group screen resolutions in classes that get prefixed to the base preset name. Define media queries for each prefix. ```xml ``` The attribute *default* set, defines the preset used for fallback images (noscript). **Tipp: px or em?** > If you want to also generate image variants optimized for hires-displays (like 4k, or at least "Retina"), it's advisable to use _em_ units and not _px_ units in your media queries. You are free to segment and structure to your liking, this allows ResponsivePresets to adapt to almost any requirement. ### 3. Configure presets Add a preset to your config, like you would normally do for the presets plugin: ```xml ``` If this setting is i.e. for standard desktop devices, prefix the preset name with *desktop.* like so: ```xml ``` Add presets for all the other prefixes (device segments) ```xml ``` ### 4. Enable "respectPixelDensity"-Setting If set to "true", ResponsivePresets will generate srcset values with 1x, 2x, 3x and 4x variants of the images by [zooming](http://imageresizing.net/docs/reference) the images accordingly. ### 5. Prepare your markup * Reference the (minified) [polyfill javascript](https://github.com/Wilto/picturefill-proposal): ```html ``` * If the pull request with my fix is not already merged, [use this corrected version of the polyfill](https://github.com/Wilto/picturefill-proposal/pull/2): * Adjust image source attribute: Instead of adding a fixed preset name to the image's request string, write the base preset name and prepend a dot to indicate you want this image to be extended by ResponsivePresets: ```html sample image ``` ---- ##Notes Your stylesheet has to take care to resize the images to the desired dimensions, they now greatly vary depending on the client's screen resolution and pixel density. Consider to also include [matchMedia](https://github.com/paulirish/matchMedia.js/). Have a look at the [picturefill compatibility chart](https://github.com/Wilto/picturefill-proposal#support). ---- ## Limitations #### Polyfill vs. browser implementation >While polyfilling does work, using it in real world sites before a major browser implements the picture tag has to be well-considered. ---- Follow [esn303](https://twitter.com/#!/esn303) on twitter This project is open to collaboration. **Fork. Push. Innovate.** \ No newline at end of file diff --git a/www/ImageResizer.config b/www/ImageResizer.config index 81ed8d1..2bfc897 100644 --- a/www/ImageResizer.config +++ b/www/ImageResizer.config @@ -6,19 +6,20 @@ - - + + - - - + + + - - - - + + + + +