开发者

How to pass multiple Property Collections to method C#

I am trying to pass a collection of objects to a method in c#.

Here are the methods. First one expects a single property to be passed.

/// <summary>
    /// Adds an EXIF property to an image.
    /// </summary>
    /// <param name="inputPath">file path of original image</param>
    /// <param name="outputPath">file path of modified image</param>
    /// <param name="property"></param>
    public static void AddExifData(string inputPath, string outputPath, ExifProperty property)
    {
        using (Image image = Image.FromFile(inputPath))
        {
            ExifWriter.AddExifData(image, property);
            image.Save(outputPath);
        }
    }

The second one expects a collection of properties. This is the method I want to pass data too.

/// <summary>
    /// Adds a collection of EXIF properties to an image.
    /// </summary>
    /// <param name="inputPath">file path of original image</param>
    /// <param name="outputPath">file path of modified image</param>
    /// <param name="properties"></param>
    public static void AddExifData(string inputPath, string outputPath, ExifPropertyCollection properties)
    {
        using (Image image = Image.FromFile(inputPath))
        {
            ExifWriter.AddExifData(image, properties);
            image.Save(outputPath);
        }
    }

To pass data as a single property I use this code.

// Add folder date to exif tag
ExifProperty folderDate = new ExifProperty();
folderDate.Tag = ExifTag.DateTime;
folderDate.Value = lastPart.ToString();

ExifWriter.AddExifData(imagePath, outputPath, copyright);

Here I only pass one property to the method. How could I send multiple items to the method like this.

// add copyright tag
ExifProperty copyright = new ExifProperty();
copyright.Tag = ExifTag.Copyright;
copyright.Value = String.Format(
       "Copyright (c){0} Lorem ipsum dolor sit amet. All rights reserved.",
       DateTime.Now.Year);

// Add folder date to exif tag
ExifProperty folderDate = new ExifProperty();
folderDate.Tag = ExifTag.DateTime;
folderDate.Value = lastPart.ToString();

Then pass both these propert开发者_开发知识库ies?

ExifWriter.AddExifData(imagePath, outputPath, ??????????);

Thanks


You're trying to create a params ExifProperty[] parameter.

public static void AddExifData(string inputPath, string outputPath, params ExifProperty[] properties)
{ ... }

ExifWriter.AddExifData(imagePath, outputPath, copyright, folderDate);


Here is the full class without the new code added.

using System;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;

namespace ExifUtils.Exif.IO
{
    /// <summary>
    /// Utility class for writing EXIF data
    /// </summary>
    public static class ExifWriter
    {
        #region Fields

        private static ConstructorInfo ctorPropertyItem = null;

        #endregion Fields

        #region Write Methods

        /// <summary>
        /// Adds a collection of EXIF properties to an image.
        /// </summary>
        /// <param name="inputPath">file path of original image</param>
        /// <param name="outputPath">file path of modified image</param>
        /// <param name="properties"></param>
        public static void AddExifData(string inputPath, string outputPath, ExifPropertyCollection properties)
        {
            using (Image image = Image.FromFile(inputPath))
            {
                ExifWriter.AddExifData(image, properties);
                image.Save(outputPath);
            }
        }

        /// <summary>
        /// Adds an EXIF property to an image.
        /// </summary>
        /// <param name="inputPath">file path of original image</param>
        /// <param name="outputPath">file path of modified image</param>
        /// <param name="property"></param>
        public static void AddExifData(string inputPath, string outputPath, ExifProperty property)
        {
            using (Image image = Image.FromFile(inputPath))
            {
                ExifWriter.AddExifData(image, property);
                image.Save(outputPath);
            }
        }

        /// <summary>
        /// Adds a collection of EXIF properties to an image.
        /// </summary>
        /// <param name="image"></param>
        /// <param name="properties"></param>
        public static void AddExifData(Image image, ExifPropertyCollection properties)
        {
            if (image == null)
            {
                throw new NullReferenceException("image was null");
            }

            if (properties == null || properties.Count < 1)
            {
                return;
            }

            foreach (ExifProperty property in properties)
            {
                ExifWriter.AddExifData(image, property);
            }
        }

        /// <summary>
        /// Adds an EXIF property to an image.
        /// </summary>
        /// <param name="image"></param>
        /// <param name="property"></param>
        public static void AddExifData(Image image, ExifProperty property)
        {
            if (image == null)
            {
                throw new NullReferenceException("image was null");
            }

            if (property == null)
            {
                return;
            }

            PropertyItem propertyItem;

            // The .NET interface for GDI+ does not allow instantiation of the
            // PropertyItem class. Therefore one must be stolen off the Image
            // and repurposed.  GDI+ uses PropertyItem by value so there is no
            // side effect when changing the values and reassigning to the image.
            if (image.PropertyItems == null || image.PropertyItems.Length < 1)
            {
                propertyItem = ExifWriter.CreatePropertyItem();
            }
            else
            {
                propertyItem = image.PropertyItems[0];
            }

            propertyItem.Id = (int)property.Tag;
            propertyItem.Type = (short)property.Type;

            Type dataType = ExifDataTypeAttribute.GetDataType(property.Tag);

            switch (property.Type)
            {
                case ExifType.Ascii:
                    {
                        propertyItem.Value = Encoding.ASCII.GetBytes(Convert.ToString(property.Value) + '\0');
                        break;
                    }
                case ExifType.Byte:
                    {
                        if (dataType == typeof(UnicodeEncoding))
                        {
                            propertyItem.Value = Encoding.Unicode.GetBytes(Convert.ToString(property.Value) + '\0');
                        }
                        else
                        {
                            goto default;
                        }
                        break;
                    }
                default:
                    {
                        throw new NotImplementedException(String.Format("Encoding for EXIF property \"{0}\" has not yet been implemented.", property.DisplayName));
                    }
            }
            propertyItem.Len = propertyItem.Value.Length;

            // This appears to not be necessary
            //foreach (int id in image.PropertyIdList)
            //{
            //    if (id == exif.PropertyItem.Id)
            //    {
            //        image.RemovePropertyItem(id);
            //        break;
            //    }
            //}
            image.SetPropertyItem(propertyItem);
        }

        #endregion Write Methods

        #region Copy Methods

        /// <summary>
        /// Copies EXIF data from one image to another
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        public static void CloneExifData(Image source, Image dest)
        {
            ExifWriter.CloneExifData(source, dest, -1);
        }

        /// <summary>
        /// Copies EXIF data from one image to another
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <param name="maxPropertyBytes">setting to filter properties</param>
        public static void CloneExifData(Image source, Image dest, int maxPropertyBytes)
        {
            bool filter = (maxPropertyBytes > 0);

            // preserve EXIF
            foreach (PropertyItem prop in source.PropertyItems)
            {
                if (filter && prop.Len > maxPropertyBytes)
                {
                    // skip large sections
                    continue;
                }

                dest.SetPropertyItem(prop);
            }
        }

        #endregion Copy Methods

        #region Utility Methods

        /// <summary>
        /// Uses Reflection to instantiate a PropertyItem
        /// </summary>
        /// <returns></returns>
        internal static PropertyItem CreatePropertyItem()
        {
            if (ExifWriter.ctorPropertyItem == null)
            {
                // Must use Reflection to get access to PropertyItem constructor
                ExifWriter.ctorPropertyItem = typeof(PropertyItem).GetConstructor(Type.EmptyTypes);
                if (ExifWriter.ctorPropertyItem == null)
                {
                    throw new NotSupportedException("Unable to instantiate a System.Drawing.Imaging.PropertyItem");
                }
            }

            return (PropertyItem)ExifWriter.ctorPropertyItem.Invoke(null);
        }

        #endregion Utility Methods
    }
}


You could use the params keyword:

public static void AddExifData(
    string inputPath, 
    string outputPath,
    params ExifProperty[] properties)
{
    using (Image image = Image.FromFile(inputPath))
    {
        ExifWriter.AddExifData(image, new ExifPropertyCollection(properties));
        image.Save(outputPath);
    }
}

And then call:

ExifWriter.AddExifData(imagePath, outputPath, copyright, folderDate);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜