/// <summary>Saves image in a particular format.</summary>
 /// <param name="newImage">Image to be saved</param>
 protected virtual void SaveImage(Bitmap newImage)
 {
     try
     {
         if (!File.Exists(this.AssembleFileName))
         {
             // This try-catch block checks if there is some GDI+ error occured while saving the image.
             // Incase an exception is thrown, remove the invalid file, if it is generated.
             newImage.Save(this.AssembleFileName, this.Format);
         }
     }
     catch (ExternalException ex)
     {
         // If ExternalException is raised then there is a problem with Image Format or
         // Image is save to the same file from where it was created. (ref: http://msdn.microsoft.com/en-us/library/9t4syfhh.aspx)
         // This exception is thrown also if access is denied to the path.
         // Handle this condition and throw a custom exception with actual exception as inner exception.
         var imageException = new ImageAssembleException(string.Format(CultureInfo.CurrentUICulture, ImageAssembleStrings.ImageSaveExternalExceptionMessage, this.AssembleFileName), ex);
         throw imageException;
     }
 }
        internal virtual bool Assemble(List <BitmapContainer> inputImages)
        {
            Bitmap newImage = null;

            try
            {
                // If there is only one image then don't pack images
                if (inputImages.HasAtLeast(2))
                {
                    // If Orientation is Auto (which is by default) then get the orientation
                    // wherein the assembled file size would be minimal.
                    // Else Pack the files according to the value specified.
                    switch (this.PackingType)
                    {
                    case SpritePackingType.Horizontal:
                        newImage = this.PackHorizontal(inputImages, true, null);
                        break;

                    case SpritePackingType.Vertical:
                        newImage = this.PackVertical(inputImages, true, null);
                        break;

                    default:
                        newImage = this.PackVertical(inputImages, true, null);
                        break;
                    }

                    if (newImage != null)
                    {
                        this.SaveAndHashImage(newImage, newImage.Width, newImage.Height);
                        return(true);
                    }
                }
                else if (inputImages.Any())
                {
                    // Pass through, used for image by themselves or images that should be hashed but not sprited.
                    var image = inputImages.First();
                    this.ImageXmlMap.AppendToXml(image.InputImage.AbsoluteImagePath, this.AssembleFileName, image.Width, image.Height, 0, 0, "passthrough", true, image.InputImage.Position);
                    image.BitmapAction(bitmap => this.SaveAndHashImage(image.Bitmap, image.Width, image.Height));
                    return(true);
                }
            }
            catch (OutOfMemoryException ex)
            {
                this.context.Log.Error(ex);

                // If there this type of exception is thrown while Image.FromFile(path)
                // then thrown a custom exception. Ref: http://msdn.microsoft.com/en-us/library/stf701f5.aspx
                var imageException = new ImageAssembleException(ImageAssembleStrings.ImageLoadOutofMemoryExceptionMessage, ex);
                throw imageException;
            }
            catch (Exception ex)
            {
                this.context.Log.Error(ex);
                try
                {
                    Safe.FileLock(
                        new FileInfo(this.AssembleFileName),
                        () =>
                    {
                        // First delete the invalid file, if it exists
                        if (File.Exists(this.AssembleFileName))
                        {
                            File.Delete(this.AssembleFileName);
                        }
                    });
                }
                catch (Exception)
                {
                }

                throw;
            }
            finally
            {
                if (newImage != null)
                {
                    newImage.Dispose();
                }
            }

            return(false);
        }