Recently, I visited the product page of fanwe product and noticed that some of the images on this page are dynamic into sprites, such:
From this image, we can see that the background image of the. spritewashings style is dynamically generated through joinimages. ashx. This idea is good, but the style is not generated. Therefore, its HTML uses style = "background-position: 0px-80px" to locate the problem. I personally think this method is not good and should be located by adding a class, in this case, you need to generate the corresponding style when generating a Sprite.
The principle of generating sprites is simple: generate a corresponding Bitmap Based on Multiple Image addresses, and draw these bitmaps to a bitmap.
The core code is as follows:
private static bool GenerateSprite(ImageSettings settings, int x, int y, List<Bitmap> images, StringBuilder cssCompatOutput) { if (settings.TileInYAxis) { y += images.Count; } else { x += images.Count; } using (Bitmap sprite = new Bitmap(x, y)) { using (Graphics drawingSurface = Graphics.FromImage(sprite)) { drawingSurface.Clear(settings.BackgroundColor); int xOffset = 0; int yOffset = 0; foreach (Bitmap image in images) { drawingSurface.DrawImage(image, new Rectangle(xOffset, yOffset, image.Width, image.Height)); if (image.Tag != null) GenerateCss(xOffset, yOffset, image, cssCompatOutput, settings); if (settings.TileInYAxis) { yOffset += image.Height + 1; } else { xOffset += image.Width + 1; } } try { using (EncoderParameters spriteEncoderParameters = new EncoderParameters(1)) { spriteEncoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, settings.Quality); sprite.Save(Path.Combine(settings.SpritePath, GenerateSpriteFileName(settings.SpriteName, settings.Format)), GetEncoderInfo(settings.Format), spriteEncoderParameters); } return true; } catch (Exception ex1) { try { sprite.Save(Path.Combine(settings.SpritePath, GenerateSpriteFileName(settings.SpriteName, settings.Format))); return true; } catch (Exception ex2) { // sprite.Save( Path.Combine(settings.SpritePath, GenerateSpriteFileName(settings.SpriteName, "png"))); return false; } } } } }
I made a simple demo. The code structure is as follows:
Spriteimage is the core code for making sprite images encapsulated into DLL, and spriteimagecreate is a form tool.
The running effect is as follows:
See the results. Our tool requires generating sprites and CSS.
Let's take a look at web references:
public ActionResult Index() { string basedirectory = Path.Combine(this.Request.PhysicalApplicationPath, "Content"); FileInfo[] files = new DirectoryInfo(Path.Combine(basedirectory, "Images")).GetFiles(); List<string> filesPath = files.Select(x => x.FullName).ToList(); ViewData.Add("Sprites", filesPath); return View(ViewData); } [ChildActionOnly] public ActionResult Sprite(List<string> images) { if (images == null || images.Count < 1) return View(); string[] filenames = images.Select(x => { int startindex = x.LastIndexOf("\\"); int endindex = x.LastIndexOf("."); return x = x.Substring(startindex + 1, endindex - startindex - 1); }).ToArray(); string spritname = string.Join("", filenames).GetHashCode().ToString(); string basedirectory = Path.Combine(this.Request.PhysicalApplicationPath, "Content/Sprites"); string cssFile = Path.Combine(basedirectory, spritname + ".css"); int index = this.Request.Url.OriginalString.LastIndexOf(this.Request.Url.LocalPath); string prfx = this.Request.Url.OriginalString.Substring(0, index); if (!System.IO.File.Exists(cssFile)) { ImageSettings setting = new ImageSettings(spritname, basedirectory) { CssSpriteUrl = prfx + "/Content/Sprites/", TileInYAxis = false }; StringBuilder sb = new StringBuilder(); var ret = ImageOptimizations.Optimizations(setting, sb, images); if (ret) { using (StreamWriter sw = new StreamWriter(cssFile, false, Encoding.UTF8)) { sw.Write(sb.ToString()); } } } if (System.IO.File.Exists(cssFile)) { string retFormat = " <link type=\"text/css\" rel=\"Stylesheet\" href=\"{0}\" />"; string url = prfx + "/Content/Sprites/" + spritname + ".css"; return Content(string.Format(retFormat, url)); } return View(); }
The purpose of index is to simulate a dynamic image address data. Let's look at your view code:
@{ ViewBag.Title = "Home Page"; var files = ViewData["Sprites"] as List<string>;}@section HeadSection{ @{ Html.RenderAction("Sprite", "Home", new { images = files });}}<div> @{ foreach (var item in files) { int index = item.LastIndexOf("\\"); string subname = item.Substring(index + 1); subname = subname.Replace(".", "_"); <div class="@subname" style="float:left " > </div> } }</div>
The code is not very simple. Check the running result:
After seeing the above HTML code, can you see that my Sprite is dynamically generated? I not only dynamically generate sprites but also styles.
The most general HTML is just a style reference
<Link type = "text/CSS" rel = "stylesheet" href = "http: // localhost: 1468/content/sprites/602820.60.css"/>
Let's take a look at our style file:
After reading my style file, you must understand the code <Div class = "joinimages1_png" style = "float: Left"> Why is class used instead of positioning.
Complete source code download