Skip to content

Commit

Permalink
Added attribute to define default preset for fallback images
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcStoecker committed Mar 10, 2013
1 parent 78dedf3 commit 0ac9487
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 53 deletions.
88 changes: 45 additions & 43 deletions plugin/FilterModule/MarkupParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# ResponsivePresets for ImageResizer.Net**Effortless reponsive images powered by ImageResizer.Net**##IntroductionLicensed 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 useResponsivePresets 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 ResponsivePresetsResponsivePresets 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 `<system.webServer>`, `<modules>`:```xml<add name="ResponsivePresetsModule" type="ResponsivePresets.FilterModule.ActivateFilterModule, ResponsivePresets"/>```For a working example see web.config and ImageResizer.config in /www/### 2. Segment device screen resolutionsThe concept for ResponsivePresets is to group screen resolutions in classes that get prefixed to the base preset name.```xml<responsivepresets respectPixelDensity="true"> <preset prefix="mobile" /> <preset prefix="desktop" media="(min-width: 960px)" /> <preset prefix="hires" media="(min-width: 2000px)" /></responsivepresets>```**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 presetsAdd a preset to your config, like you would normally do for the presets plugin: ```xml<preset name="galleryimage" settings="width=800" />```If this setting is i.e. for standard desktop devices, prefix the preset name with *desktop.* like so: ```xml<preset name="desktop.galleryimage" settings="width=800" />```Add presets for all the other prefixes (device segments) ```xml<preset name="mobile.galleryimage" settings="width=400" /><preset name="desktop.galleryimage" settings="width=800" /><preset name="hires.galleryimage" settings="width=1600" />```### 4. Enable "respectPixelDensity"-SettingIf 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 <script src="/picturefill.js"></script>```* 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 <img src="sample.jpg?preset=.galleryimage" alt="sample image"/>```----##NotesYour 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 twitterThis project is open to collaboration. **Fork. Push. Innovate.**
# ResponsivePresets for ImageResizer.Net**Effortless reponsive images powered by ImageResizer.Net**##IntroductionLicensed 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 useResponsivePresets 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 ResponsivePresetsResponsivePresets 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 `<system.webServer>`, `<modules>`:```xml<add name="ResponsivePresetsModule" type="ResponsivePresets.FilterModule.ActivateFilterModule, ResponsivePresets"/>```For a working example see web.config and ImageResizer.config in /www/### 2. Segment device screen resolutionsThe 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<responsivepresets respectPixelDensity="true"> <preset prefix="mobile" /> <preset prefix="desktop" media="(min-width: 960px)" default="true" /> <preset prefix="hires" media="(min-width: 2000px)" /></responsivepresets>```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 presetsAdd a preset to your config, like you would normally do for the presets plugin: ```xml<preset name="galleryimage" settings="width=800" />```If this setting is i.e. for standard desktop devices, prefix the preset name with *desktop.* like so: ```xml<preset name="desktop.galleryimage" settings="width=800" />```Add presets for all the other prefixes (device segments) ```xml<preset name="mobile.galleryimage" settings="width=400" /><preset name="desktop.galleryimage" settings="width=800" /><preset name="hires.galleryimage" settings="width=1600" />```### 4. Enable "respectPixelDensity"-SettingIf 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 <script src="/picturefill.js"></script>```* 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 <img src="sample.jpg?preset=.galleryimage" alt="sample image"/>```----##NotesYour 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 twitterThis project is open to collaboration. **Fork. Push. Innovate.**
Expand Down
19 changes: 10 additions & 9 deletions www/ImageResizer.config
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
<diagnostics enableFor="Localhost" /> <!-- AllHosts, None -->

<plugins>
<add name="DiskCache" /> <!-- requires Performance Bundle (licence) -->
<add name="Presets" /> <!-- Free bundle -->
<add name="DiskCache" /> <!-- requires Performance Bundle (licence) -->
<add name="Presets" /> <!-- Free bundle -->
</plugins>

<presets onlyAllowPresets="false">
<preset name="mobile.galleryimage" settings="width=400" />
<preset name="desktop.galleryimage" settings="width=1500" />
<preset name="hires.galleryimage" settings="width=2400" />
<preset name="mobile.galleryimage" settings="width=400" />
<preset name="desktop.galleryimage" settings="width=1500" />
<preset name="hires.galleryimage" settings="width=2400" />
</presets>

<responsivepresets respectPixelDensity="true">
<preset prefix="mobile" />
<preset prefix="desktop" media="(min-width: 960px)" />
<preset prefix="hires" media="(min-width: 2000px)" />
<!-- tagmode: picture|img-->
<responsivepresets tagmode="picture" respectPixelDensity="true">
<preset prefix="mobile" />
<preset prefix="desktop" media="(min-width: 960px)" default="true" />
<preset prefix="hires" media="(min-width: 2000px)" />
</responsivepresets>
</resizer>

0 comments on commit 0ac9487

Please sign in to comment.