public SpritedImage(int averageColor, BackgroundImageClass cssClass, Bitmap image) { AverageColor = averageColor; CssClass = cssClass; Image = image; Position = -1; }
private static void InheritMissingProperties(BackgroundImageClass derrivableClass, BackgroundImageClass imageClass) { if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasYOffset)) imageClass.YOffset = derrivableClass.YOffset; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasXOffset)) imageClass.XOffset = derrivableClass.XOffset; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasRepeat)) imageClass.Repeat = derrivableClass.Repeat; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasImage)) imageClass.ImageUrl = derrivableClass.ImageUrl; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasPaddingBottom)) imageClass.PaddingBottom = derrivableClass.PaddingBottom; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasPaddingTop)) imageClass.PaddingTop = derrivableClass.PaddingTop; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasPaddingLeft)) imageClass.PaddingLeft = derrivableClass.PaddingLeft; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasPaddingRight)) imageClass.PaddingRight = derrivableClass.PaddingRight; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasWidth)) imageClass.ExplicitWidth = derrivableClass.ExplicitWidth; if (DerivableHasMissingProperty(derrivableClass, imageClass, PropertyCompletion.HasHeight)) imageClass.ExplicitHeight = derrivableClass.ExplicitHeight; }
public IEnumerable<BackgroundImageClass> ExtractImageUrls(string cssContent) { var finalUrls = new List<BackgroundImageClass>(); var draftUrls = new List<BackgroundImageClass>(); var classCounter = 0; foreach (var classMatch in classPattern.Matches(cssContent)) { var imageClass = new BackgroundImageClass(classMatch.ToString(), ++classCounter); if (!ShouldFlatten(imageClass)) continue; if (!IsComplete(imageClass) && ShouldFlatten(imageClass)) { var workList = new List<BackgroundImageClass>(); for (var n = draftUrls.Count - 1; n > -1; n--) { var selectors = draftUrls[n].Selector.Split(new [] {','}); var targetSelectors = imageClass.Selector.Split(new[] { ',' }); foreach (var selector in selectors) { if (targetSelectors .Any(targetSelector => cssSelectorAnalyzer.IsInScopeOfTarget(targetSelector.Trim(), selector.Trim()))) workList.Add(draftUrls[n]); } } workList.Sort(selectorComparer); foreach (var cls in workList.Where(cls => !IsComplete(imageClass))) InheritMissingProperties(cls, imageClass); } draftUrls.Add(imageClass); if (CanSprite(imageClass)) finalUrls.Add(imageClass); } return finalUrls; }
private static bool DerivableHasMissingProperty(BackgroundImageClass derrivableClass, BackgroundImageClass imageClass, PropertyCompletion property) { if ((imageClass.PropertyCompletion & property) != property && (derrivableClass.PropertyCompletion & property) == property) { imageClass.PropertyCompletion = imageClass.PropertyCompletion | property; return true; } return false; }
public virtual void Add(BackgroundImageClass image) { if (ImageExclusionFilter != null && ImageExclusionFilter(image)) return; var imageKey = new ImageMetadata(image); if (spriteList.Any(x => x.Key.Equals(imageKey))) { var originalImage = spriteList.First(x => x.Key.Equals(imageKey)).Value; var clonedImage = new SpritedImage(originalImage.AverageColor, image, originalImage.Image) { Position = originalImage.Position, Url = originalImage.Url, Metadata = imageKey }; spriteList.Add(new KeyValuePair<ImageMetadata, SpritedImage>(imageKey, clonedImage)); return; } SpritedImage spritedImage; var sprite = spriteList.FirstOrDefault(x => x.Value.CssClass.ImageUrl == image.ImageUrl); if(sprite.Value != null) { image.IsSprite = true; sprite.Value.CssClass.IsSprite = true; } try { spritedImage = SpriteContainer.AddImage(image); spritedImage.Metadata = imageKey; } catch (Exception ex) { var message = string.Format("There were errors reducing {0}", image.ImageUrl); Tracer.Trace(message); Tracer.Trace(ex.ToString()); var wrappedException = new SpriteException(image.OriginalClassString, message, ex); Errors.Add(wrappedException); return; } spriteList.Add(new KeyValuePair<ImageMetadata, SpritedImage>(imageKey, spritedImage)); if (SpriteContainer.Size >= config.SpriteSizeLimit || (SpriteContainer.Colors >= config.SpriteColorLimit && !config.ImageQuantizationDisabled && !config.ImageOptimizationDisabled)) Flush(); }
private bool CanSprite(BackgroundImageClass imageClass) { if (imageClass.ImageUrl == null) return false; if (imageClass.Width > 0 && imageClass.Repeat == RepeatStyle.NoRepeat && ((imageClass.YOffset.PositionMode == PositionMode.Direction) || (imageClass.YOffset.PositionMode == PositionMode.Percent) || ((imageClass.YOffset.PositionMode == PositionMode.Unit) && (imageClass.YOffset.Offset >= 0 || imageClass.Height > 0)))) return true; return false; }
private bool ShouldFlatten(BackgroundImageClass imageClass) { if ((imageClass.PropertyCompletion & PropertyCompletion.HasImage) == PropertyCompletion.HasImage) return true; if ((imageClass.PropertyCompletion & PropertyCompletion.HasXOffset) == PropertyCompletion.HasXOffset) return true; if ((imageClass.PropertyCompletion & PropertyCompletion.HasYOffset) == PropertyCompletion.HasYOffset) return true; return false; }
private bool IsComplete(BackgroundImageClass imageClass) { return (imageClass.PropertyCompletion & (PropertyCompletion.HasHeight | PropertyCompletion.HasImage | PropertyCompletion.HasPaddingBottom | PropertyCompletion.HasPaddingLeft | PropertyCompletion.HasPaddingRight | PropertyCompletion.HasPaddingTop | PropertyCompletion.HasRepeat | PropertyCompletion.HasWidth | PropertyCompletion.HasXOffset | PropertyCompletion.HasYOffset)) == (PropertyCompletion.HasHeight | PropertyCompletion.HasImage | PropertyCompletion.HasPaddingBottom | PropertyCompletion.HasPaddingLeft | PropertyCompletion.HasPaddingRight | PropertyCompletion.HasPaddingTop | PropertyCompletion.HasRepeat | PropertyCompletion.HasWidth | PropertyCompletion.HasXOffset | PropertyCompletion.HasYOffset); }
public SpritedImage AddImage (BackgroundImageClass image) { byte[] imageBytes; if(DownloadedImages.ContainsKey(image.ImageUrl) && image.IsSprite) imageBytes = DownloadedImages[image.ImageUrl]; else { imageBytes = ImageLoader.GetImageBytes(image.ImageUrl); if(image.IsSprite) DownloadedImages.Add(image.ImageUrl, imageBytes); } Bitmap bitmap; using (var originalBitmap = new Bitmap(new MemoryStream(imageBytes))) { var width = image.Width ?? originalBitmap.Width; //cliped width of original image var height = image.Height ?? originalBitmap.Height; using (var writer = new SpriteWriter(width, height)) { var x = image.XOffset.Offset < 0 ? Math.Abs(image.XOffset.Offset) : 0; //offset on original var y = image.YOffset.Offset < 0 ? Math.Abs(image.YOffset.Offset) : 0; var imageWidth = width; //canvas width if (width + x > originalBitmap.Width) width = originalBitmap.Width - x; var imageHeight = height; if (height + y > originalBitmap.Height) height = originalBitmap.Height - y; var offsetX = 0; var offsetY = 0; if (image.XOffset.PositionMode == PositionMode.Direction) { switch (image.XOffset.Direction) { case Direction.Left: image.XOffset = new Position { PositionMode = PositionMode.Percent, Offset = 0}; break; case Direction.Center: image.XOffset = new Position { PositionMode = PositionMode.Percent, Offset = 50}; break; case Direction.Right: image.XOffset = new Position { PositionMode = PositionMode.Percent, Offset = 100 }; break; } } if (image.YOffset.PositionMode == PositionMode.Direction) switch (image.YOffset.Direction) { case Direction.Top: image.YOffset = new Position { PositionMode = PositionMode.Percent, Offset = 0 }; break; case Direction.Center: image.YOffset = new Position { PositionMode = PositionMode.Percent, Offset = 50 }; break; case Direction.Bottom: image.YOffset = new Position { PositionMode = PositionMode.Percent, Offset = 100 }; break; } if (image.XOffset.PositionMode == PositionMode.Percent) { if (originalBitmap.Width > imageWidth) x = (int)Math.Round((originalBitmap.Width - imageWidth) * (image.XOffset.Offset / 100f), 0); else offsetX = (int)Math.Round((imageWidth - originalBitmap.Width) * (image.XOffset.Offset / 100f), 0); } else if (image.XOffset.PositionMode == PositionMode.Unit && image.XOffset.Offset > 0) { offsetX = image.XOffset.Offset; if (originalBitmap.Width + offsetX > imageWidth) width = imageWidth - offsetX; } if (image.YOffset.PositionMode == PositionMode.Percent) { if (originalBitmap.Height > imageHeight) y = (int)Math.Round((originalBitmap.Height - height) * (image.YOffset.Offset / 100f), 0); else offsetY = (int)Math.Round((imageHeight - originalBitmap.Height) * (image.YOffset.Offset / 100f), 0); } try { using (var bm = originalBitmap.Clone(new Rectangle(x, y, width, height), originalBitmap.PixelFormat)) { writer.WriteImage(bm, offsetX, offsetY); } } catch (OutOfMemoryException) { throw new InvalidOperationException(string.Format("Unable to Add {0} to Sprite.", image.ImageUrl)); } bitmap = writer.SpriteImage; if ((originalBitmap.Width * originalBitmap.Height) > (bitmap.Width * bitmap.Height)) Size += writer.GetBytes("image/png").Length; else Size += imageBytes.Length; } } var avgColor = settings.IsFullTrust ? GetColors(bitmap) : 0; var spritedImage = new SpritedImage(avgColor, image, bitmap); Images.Add(spritedImage); Width += bitmap.Width + 1; if (Height < bitmap.Height) Height = bitmap.Height; return spritedImage; }
public ImageMetadata(BackgroundImageClass image) : this() { Url = image.ImageUrl; Width = image.Width ?? 0; Height = image.Height ?? 0; XOffset = image.XOffset.Offset; YOffset = image.YOffset.Offset; }