<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://jamessouth.me/blog/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>James Jackson-South</title>
    <link>http://jamessouth.me/blog/</link>
    <description>Microsoft MVP, Creator of ImageSharp, ImageProcessor and ResponsiveBP, Web developer, Lifter of heavy weights, and all round nice guy.</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <item>
      <guid isPermaLink="false">1122</guid>
      <link>http://jamessouth.me/archive/mo-images-mo-processing/</link>
      <category>System.String[]</category>
      <title>Mo Images Mo Processing</title>
      <description>&lt;p&gt;Today marks another big ImageProcessor release, and my first antipodean one - There's a lot going on so here's a run through of new functionality that's been added to &lt;strong&gt;Imageprocessor v2.4&lt;/strong&gt; and &lt;strong&gt;ImageProcessor.Web. v4.4&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr... Upgrade&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;ImageProcessor&lt;/h1&gt;
&lt;h2&gt;New Stuff&lt;/h2&gt;
&lt;h3&gt;Resolution&lt;/h3&gt;
&lt;p&gt;This method allows you to change the resolution of the given image. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public ImageFactory Resolution(int horizontal, int vertical, PropertyTagResolutionUnit unit = PropertyTagResolutionUnit.Inch)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If any EXIF data is to be preserved, the metadata will be updated to match the given resolution.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Resize&lt;/h3&gt;
&lt;p&gt;With this release I've added two new resize modes to the library: &lt;code&gt;ResizeMode.BoxPad&lt;/code&gt; and &lt;code&gt;ResizeMode.Min&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResizeMode.BoxPad&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;When upscaling an image using this mode the image pixels themselves are not resized, rather the image is padded to fit the given dimensions. When downscaling the image is resized using the rules defined by &lt;code&gt;ResizeMode.Pad&lt;/code&gt;. As with that mode you can recolour the background colour of the padded area for image types without transparency from the default black.&lt;/p&gt;
&lt;p&gt;Here's an example resizing the original to 500x500px:&lt;/p&gt;
&lt;div class="row"&gt;
&lt;div class="col-m-6"&gt;
 &lt;h4&gt;Original Image &lt;/h4&gt;
&lt;img src="http://jamessouth.me/blog/media/1046/car-small.jpg"/&gt;
&lt;/div&gt;
&lt;div class="col-m-6"&gt;
&lt;h4&gt;Padded Image With Hot Pink Background &lt;/h4&gt;
&lt;img src="http://jamessouth.me/blog/media/1046/car-small.jpg?width=500&amp;height=500&amp;mode=boxpad&amp;bgcolor=hotpink"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As with &lt;code&gt;ResizeMode.Pad&lt;/code&gt; and &lt;code&gt;ResizeMode.Crop&lt;/code&gt; the position of the image can be anchored to one of nine different anchor points.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResizeMode.Min&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;This mode looks for the shortest difference in each dimension between the source length and intended length. it will then resize that side to the intended length on the result, the other dimension is resized maintaining the aspect ratio of the original image. Upscaling is disabled in this mode and the original image will be returned if attempted.&lt;/p&gt;
&lt;p&gt;Here's an example downscaling a larger version of the original with target dimensions of  500x500px:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://jamessouth.me/blog/media/1006/car.jpg?width=500&amp;amp;height=500&amp;amp;mode=min" alt="Image resized using ResizeMode.Min" /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Performance&lt;/h2&gt;
&lt;p&gt;I've managed to reduce the memory usage by up to 25% in some circumstances in this version by rewriting the way I ensure certain methods performs their functionality in the correct colour space. These rewrites have also slightly improved the speed on earlier releases which is a nice bonus.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Bug fixes&lt;/h2&gt;
&lt;p&gt;In this release I've ironed out numerous bugs relating to image resolution. EXIF metadata for any method that changes the dimension of the image are now updated also where previously this was overlooked.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;ImageProcessor.Web&lt;/h1&gt;
&lt;h2&gt;New Stuff&lt;/h2&gt;
&lt;h3&gt;PostProcessing&lt;/h3&gt;
&lt;p&gt;This is a big one and I'm very pleased with it...&lt;/p&gt;
&lt;p&gt;I'm all about keeping the web lean but the default image encoders in .NET are not that efficient and you can sometimes actually end up with a &lt;a href="https://github.com/JimBobSquarePants/ImageProcessor/issues/208"&gt;larger image&lt;/a&gt; than what you started with. As such, I've been looking at a way to ensure that anything I output has been optimised as much as possible. For previous versions of &lt;strong&gt;ImageProcessor.Web&lt;/strong&gt; I developed a plugin that post-processed any newly cached images using a variety of tools to reduce the file size as much as possible.  
&lt;/p&gt;
&lt;p&gt;This worked... To a point. Firstly it only worked with the disk cache and not any other cache plugins. Secondly it only acted after the first requests so someone, somewhere would always get an unoptimised image, Thirdly one of the tools I used, optipng was incorrectly detected as malware by Windows Defender.... Not good enough.&lt;/p&gt;
&lt;p&gt;As of this version, &lt;strong&gt;every image that is processed using ImageProcessor.Web is passed through a series of tools that reduce the output size&lt;/strong&gt;. This works with whatever cache implementation is used and can dramatically reduce the weight of your pages. This all happens asynchronously and stays snappy so you shouldn't notice any increased processing time.&lt;/p&gt;
&lt;p&gt;Here's the built in tools I use so you can check them out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gifsicle : http://www.lcdf.org/gifsicle/&lt;/li&gt;
&lt;li&gt;pngout : http://advsys.net/ken/utils.htm#pngout&lt;/li&gt;
&lt;li&gt;pngquant : https://pngquant.org/&lt;/li&gt;
&lt;li&gt;jpegtran : http://jpegclub.org/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's possible to turn off this behaviour vie the &lt;a href="http://imageprocessor.org/imageprocessor-web/configuration/"&gt;config&lt;/a&gt; but you really shouldn't.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Bug fixes&lt;/h3&gt;
&lt;p&gt;There's been various minor little issues I've found and fixed while building this update, one of note though was an &lt;a href="https://github.com/JimBobSquarePants/ImageProcessor/issues/211"&gt;issue&lt;/a&gt; where prefix values were globally replaced within the request url.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;So... What's Next?&lt;/h1&gt;
&lt;p&gt;For me this release marks the last I shall actively work on in this major version.  It might well be the last I do ever depending on what Microsoft do with graphics with the next .NET releases. I've fallen out of love with the open source community a little over the years due to the lack of collaboration I've received on this project and others. &lt;/p&gt;
&lt;p&gt;When I started ImageProcessor I didn't know much about images. I was a front end developer who decided to have a go at solving a problem colleagues were struggling with. I'd only been writing C# for a very short while and I was learning as I went on.... I still am. &lt;/p&gt;
&lt;p&gt;These libraries are now hugely popular with hundreds of thousands of downloads but the number of people who contribute is still minuscule. If I can write this stuff I guarantee there are a very great number of people out there who could do it and do it better. &lt;/p&gt;
&lt;p&gt;I'm very grateful for the work and encouragement of the team at Umbraco for their faith in me and contribution to my code but I feel somewhat that they are alone in doing what they do best in promoting a healthy community around developers.&lt;/p&gt;
&lt;p&gt;I'll still fix bugs but I will not add any more new features nor work on making the library cross-platform for now. It's simply too much work for me to do.&lt;/p&gt;
&lt;h3&gt;Help Me To Help You&lt;/h3&gt;
&lt;p&gt;If you want to see ImageProcessor continue and you know anyone with the chops to help me or think you can spend an hour a week tinkering away, please get in touch. I'd love to build a &lt;a href="https://github.com/JimBobSquarePants/ImageProcessor/tree/5c94066bc5e020d9fc34364573c62c049aa5103f"&gt;v3&lt;/a&gt; as part of a community of developers creating something amazing.&lt;/p&gt;
&lt;p&gt;Anyhoo... Enjoy the new releases. As ever you can read about them in the documentation and download them from Nuget.&lt;/p&gt;
</description>
      <pubDate>Sun, 20 Sep 2015 04:16:08 Z</pubDate>
      <a10:updated>2015-09-20T04:16:08Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1117</guid>
      <link>http://jamessouth.me/archive/cruncher-v3/</link>
      <category>System.String[]</category>
      <title>Cruncher v3</title>
      <description>&lt;h1&gt;No More &lt;kbd&gt;Ctrl-F5&lt;/kbd&gt;&lt;/h1&gt;
&lt;p&gt;Last night  at a ridiculous hour I released the latest version of my asset preprocessor for .NET&lt;/p&gt;
&lt;p&gt;Cruncher is a cool bit of kit. It makes optimizing your resources easy. It can bundle unlimited combinations of remote and local CSS, Less, Sass, JavaScript, and CoffeeScript files. Like really... Mix and match them anyway you like and Cruncher will preprocess them accordingly and produce links to the processed output.&lt;/p&gt;
&lt;p&gt;Cruncher can handle nested CSS &lt;code&gt;@import&lt;/code&gt; statements, re-maps relative resource urls and has a self cleaning cache should any changes be made to any of the referenced files. It can also parse CSS and add vendor prefixes to rules by &lt;a href="http://caniuse.com/"&gt;Can I Use&lt;/a&gt; using &lt;a href="https://github.com/postcss/autoprefixer"&gt;AutoPrefixer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can, and most definitely should get it &lt;a href="https://www.nuget.org/packages/Cruncher/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;How it works&lt;/h2&gt;
&lt;p&gt;When processing a collection of inputs, Cruncher will identify the content type and apply the correct preprocessor to the input converting it to CSS or JavaScript accordingly. CSS files are then passed through an AutoPrefixer postprocessor if it is enabled (By default it is). It will then, if you are running in release mode minify the output using the &lt;a href="http://ajaxmin.codeplex.com/"&gt;Microsoft Ajax Minifier&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Finally links are produced in the page as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;/assets-cruncher/-1287271604.css&amp;quot;&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/assets-cruncher/-1661000378.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where the name is the hash of the combined output. This allows the native static file handler to take over which is great for performance (though all this activity is also heavily cached both in the browser and the server).  If any changes are detected by file monitors for each file and imported files then the number will change which forces the browser to request the updated output. That allows instant propagation of changes made to the input files. No More &lt;kbd&gt;Ctrl-F5&lt;/kbd&gt;!&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;It really couldn't be easier. Simply add &lt;code&gt;@using Cruncher&lt;/code&gt; to your view and use the following methods to add resources. This all works in webforms syntax also.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Default.
@CruncherBundler.RenderCSS(&amp;quot;style.css&amp;quot;, &amp;quot;style.less&amp;quot;, &amp;quot;style.scss&amp;quot;)

// Render the link wth a media query.
@CruncherBundler.RenderCSS(new HtmlString(&amp;quot;media=\&amp;quot;(max-width: 800px)\&amp;quot;&amp;quot;), &amp;quot;style.css&amp;quot;, &amp;quot;style.less&amp;quot;, &amp;quot;style.scss&amp;quot;)

// Default.
@CruncherBundler.RenderJavaScript(&amp;quot;jquery-2.1.1&amp;quot;, &amp;quot;test.coffee&amp;quot;, &amp;quot;test.js&amp;quot;)

// Render the script with the 'async' boolean enabled.
@CruncherBundler.RenderJavaScript(JavaScriptLoadBehaviour.Async, &amp;quot;jquery-2.1.1&amp;quot;, &amp;quot;test.coffee&amp;quot;, &amp;quot;test.js&amp;quot;)

// Render the script with the 'defer' boolean enabled.
@CruncherBundler.RenderJavaScript(JavaScriptLoadBehaviour.Defer, &amp;quot;jquery-2.1.1&amp;quot;, &amp;quot;test.coffee&amp;quot;, &amp;quot;test.js&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's a great writeup of the &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;defer&lt;/code&gt; attributes &lt;a href="http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Feel free to have a good look through the &lt;a href="https://github.com/JimBobSquarePants/Cruncher"&gt;sourcecode&lt;/a&gt;. It's all, as ever, open source under the Apache 2.0 license and contributions are most welcome.&lt;/p&gt;
&lt;h2&gt;Thanks&lt;/h2&gt;
&lt;p&gt;I'd very much like to thank both &lt;a href="https://github.com/Alain-es"&gt;Alain (I'm so sorry I have forgotten your surname)&lt;/a&gt; for providing some simply awesome ideas and code and &lt;a href="https://github.com/jbreuer"&gt;Jeroen Breuer&lt;/a&gt; for reporting bugs and providing me with projects to tests against for this release. You both got me revisiting code I'd long forgotten about and didn't realise anyone was using. &lt;/p&gt;
</description>
      <pubDate>Sun, 30 Nov 2014 03:17:44 Z</pubDate>
      <a10:updated>2014-11-30T03:17:44Z</a10:updated>
    </item>
  </channel>
</rss>