Exemple #1
0
 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;
 }
Exemple #5
0
        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;
        }
Exemple #10
0
 public ImageMetadata(BackgroundImageClass image)
     : this()
 {
     Url = image.ImageUrl;
     Width = image.Width ?? 0;
     Height = image.Height ?? 0;
     XOffset = image.XOffset.Offset;
     YOffset = image.YOffset.Offset;
 }