public static IEnumerable<Action> GenerateActions(Config config, string path, IEnumerable<string> imageNames, string destination, Dictionary<string, Dictionary<string, string>> replacementStrings)
 {
     foreach (var imageName in imageNames)
     {
         yield return new Resizer()
         {
             config = config,
             imagePath = Path.Combine(path, imageName),
             imageName = imageName,
             destination = destination,
             strings = replacementStrings[imageName]
         }.Resize;
     }
 }
        private void Resize(Image image, Config.Size size, string imagePath, string destinationPath)
        {
            if (".jpg" != Path.GetExtension(destinationPath))
            {
                var destination = Path.GetDirectoryName(destinationPath);
                var destinationFileName = Path.GetFileNameWithoutExtension(destinationPath);
                destinationPath = Path.Combine(destination, destinationFileName + ".jpg");
            }

            if (File.Exists(destinationPath))
            {
                File.Delete(destinationPath);
            }

            int resizedWidth;
            int resizedHeight;

            double aspectRatio = Convert.ToDouble(image.Width) / Convert.ToDouble(image.Height);
            double inverseAspectRatio = Convert.ToDouble(image.Height) / Convert.ToDouble(image.Width);

            // First, figure out what the size of the returned image will be based on specified height or width

            if (null != size.Pixels)
            {
                // area = width * height;
                // aspectRatio = width / height;

                // width = area / height;
                // width = height * aspectRatio;
                // height = area / width;
                // height = width / aspectRatio;

                // width = area / (width / aspectRatio)
                // width^2 / aspectRatio = area
                // width^2 = area * aspectRatio
                // width = sqrt(area * aspectRatio)

                // height = area / (height * aspectRatio)
                // height^2 * aspectRatio = area
                // height^2 = area / aspectRatio
                // height = sqrt(area / aspectRatio)

                resizedWidth = Convert.ToInt32(Math.Sqrt(aspectRatio * Convert.ToDouble(size.Pixels.Value)));
                resizedHeight = Convert.ToInt32(Math.Sqrt(Convert.ToDouble(size.Pixels.Value) / aspectRatio));
            }
            else if ((null != size.Width) && (null != size.Height))
            {
                resizedHeight = size.Height.Value;
                resizedWidth = size.Width.Value;
                aspectRatio = Convert.ToDouble(resizedWidth) / Convert.ToDouble(resizedHeight);
                inverseAspectRatio = Convert.ToDouble(resizedHeight) / Convert.ToDouble(resizedWidth);
            }
            else if (null != size.Width)
            {
                resizedWidth = size.Width.Value;
                resizedHeight = Convert.ToInt32(
                    Convert.ToDouble(size.Width.Value) * inverseAspectRatio);
            }
            else if (null != size.Height)
            {
                resizedHeight = size.Height.Value;
                resizedWidth = Convert.ToInt32(
                    Convert.ToDouble(size.Height.Value) * aspectRatio);
            }
            else
            {
                resizedWidth = image.Width;
                resizedHeight = image.Height;
            }

            // Second, make sure that maxes and mins aren't violated

            if (null != size.MaxWidth)
                if (resizedWidth > size.MaxWidth.Value)
            {
                resizedWidth = size.MaxWidth.Value;
                resizedHeight = Convert.ToInt32(
                    Convert.ToDouble(size.MaxWidth.Value) * inverseAspectRatio);
            }

            if (null != size.MaxHeight)
                if (resizedHeight > size.MaxHeight.Value)
            {
                resizedHeight = size.MaxHeight.Value;
                resizedWidth = Convert.ToInt32(
                    Convert.ToDouble(size.MaxHeight.Value) * aspectRatio);
            }

            if (null != size.MinWidth)
                if (resizedWidth < size.MinWidth.Value)
            {
                resizedWidth = size.MinWidth.Value;
                resizedHeight = Convert.ToInt32(
                    Convert.ToDouble(size.MinWidth.Value) * inverseAspectRatio);
            }

            if (null != size.MinHeight)
                if (resizedHeight < size.MinHeight.Value)
            {
                resizedHeight = size.MinHeight.Value;
                resizedWidth = Convert.ToInt32(
                    Convert.ToDouble(size.MinHeight.Value) * aspectRatio);
            }

            this.strings[size.Name + "_height"] = resizedHeight.ToString();
            this.strings[size.Name + "_width"] = resizedWidth.ToString();
            this.strings[size.Name + "_image"] = size.Name + "/" + Path.GetFileName(destinationPath);

            // Now, in the rare chance that size doesn't change, and there's no quality set, don't do anything
            if ((resizedWidth == image.Width) && (resizedHeight == image.Height) && (null == size.Quality))
            {
                File.Copy(this.imagePath, destinationPath);

                var len = new FileInfo(this.imagePath).Length;

                this.strings[size.Name + "_sizebytes"] = len.ToString();
                this.strings[size.Name + "_size"] = Resizer.GenerateSize(len);
            }
            else
            {
                // The image must be resized.
                // reference: http://www.glennjones.net/Post/799/Highqualitydynamicallyresizedimageswithnet.htm

                var thumbnail = new Bitmap(resizedWidth, resizedHeight);
                Graphics graphic = System.Drawing.Graphics.FromImage(thumbnail);

                // Set up high-quality resize mode
                graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphic.SmoothingMode = SmoothingMode.AntiAlias;
                graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
                graphic.CompositingQuality = CompositingQuality.HighQuality;

                // do the resize
                graphic.DrawImage(image, 0, 0, resizedWidth, resizedHeight);

                // Save as a high quality JPEG
                var info = ImageCodecInfo.GetImageEncoders();
                var encoderParameters = new EncoderParameters(1);
                encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, size.Quality ?? 90L);

                using (var stream = File.OpenWrite(destinationPath))
                {
                    thumbnail.Save(stream, info[1], encoderParameters);

                    this.strings[size.Name + "_sizebytes"] = stream.Length.ToString();
                    this.strings[size.Name + "_size"] = Resizer.GenerateSize(stream.Length);

                    stream.Flush();
                    stream.Close();
                }
            }
        }
Beispiel #3
0
        public static void Main(string[] args)
        {
            try
            {
                var configFile = "config.xml";

                if (args.Length > 0)
                {
                    configFile = args[0];
                }

                configFile = Path.GetFullPath(configFile);

                var config = new Config(configFile);

                string path;
                if (args.Length > 1)
                {
                    path = Path.GetFullPath(args[1]);
                }
                else
                {
                    path = Environment.CurrentDirectory;
                }

                string destination;
                if (args.Length > 2)
                {
                    destination = Path.GetFullPath(args[2]);
                }
                else
                {
                    destination = Path.Combine(path, "generated");
                }

                if (false == Directory.Exists(destination))
                {
                    Directory.CreateDirectory(destination);
                }

                var title = "Image Gallery";
                if (args.Length > 3)
                {
                    title = args[3];
                }

                foreach (var size in config.Sizes)
                {
                    var sizePath = Path.Combine(destination, size.Name);
                    if (false == Directory.Exists(sizePath))
                    {
                        Directory.CreateDirectory(sizePath);
                    }
                }

                var imageFilesAndDates = MainClass.GetImageFilesAndDates(path);
                var imageNames = imageFilesAndDates.Keys.OrderBy(n => imageFilesAndDates[n]).ToArray();

                var replacementStrings = new Dictionary<string, Dictionary<string, string>>();

                foreach (var imageName in imageNames)
                {
                    var strings = new Dictionary<string, string>();
                    replacementStrings[imageName] = strings;

                    strings["name"] = imageName;

                    var date = imageFilesAndDates[imageName];
                    var localDate = date.ToLocalTime();
                    strings["date_long"] = localDate.ToLongDateString();
                    strings["time_long"] = localDate.ToLongTimeString();
                    strings["date_short"] = localDate.ToShortDateString();
                    strings["time_short"] = localDate.ToShortTimeString();
                    strings["datetime_milliseconds"] = (date - MainClass.JavascriptEpoc).TotalMilliseconds.ToString("R");
                    strings["datetime_net"] = date.ToString("o");
                    strings["datetime"] = date.ToString("r");
                }

                MainClass.actions = new Queue<Action>(Resizer.GenerateActions(config, path, imageNames, destination, replacementStrings));

                var threads = new List<Thread>();
                for (var ctr = 0; ctr < Environment.ProcessorCount - 1; ctr++)
                {
                    var thread = new Thread(MainClass.DoWork)
                    {
                        Name = "Thread " + ctr.ToString()
                    };
                    thread.Start();

                    threads.Add(thread);
                }

                MainClass.DoWork();

                foreach (var thread in threads)
                {
                    thread.Join();
                }

                var templatePath = Path.GetDirectoryName(configFile);
                foreach (var template in config.Templates)
                {
                    TemplateXmlGenerator.GenerateTemplate(Path.Combine(templatePath, template.File), destination, imageNames, replacementStrings, title);
                }

                foreach (var template in config.Details)
                {
                    TemplateXmlGenerator.GenerateDetails(Path.Combine(templatePath, template.File), destination, imageNames, replacementStrings, title);
                }

                foreach (var copyFile in config.CopyFiles)
                {
                    var sourceFileName = Path.Combine(templatePath, copyFile.File);
                    var destFileName = Path.Combine(destination, copyFile.File);

                    if (File.Exists(destFileName))
                    {
                        File.Delete(destFileName);
                    }

                    File.Copy(sourceFileName, destFileName);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }