Sprite graph for web optimization-dynamic generation of Sprite images read what the fanke product page thinks

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.