3

enter image description here In my project, i have to set an image rating value in any format (*.png, *.jpg, *.bmp etc.), and return the value. I try to use PropertyItem. it doesnt work.

Image im = Image.FromFile("D:\\2.jpg");
int intValue = 3;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)Array.Reverse(intBytes);
byte[] result = intBytes;
PropertyItem prop = im.GetPropertyItem(18246);
prop.Value = result;
im.SetPropertyItem(prop);

Does any one do this, if yes how, thanks?

  • 3
    could you provide your simple code? – Rang Aug 19 '14 at 09:38
  • 1
    [MSDN on PropertyItem](http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem%28v=vs.110%29.aspx): _A PropertyItem object is used to retrieve and to change the metadata of existing image files, not to create the metadata._ So, no if there is no rating present I guess you will have to use another way. – TaW Aug 19 '14 at 09:44
  • Sry guys, i have edited.`@Rang`, `@Zafarbek` – user3819845 Aug 19 '14 at 09:57
  • http://stackoverflow.com/questions/226973/how-to-edit-exif-data-in-net – CodeCaster Aug 19 '14 at 10:37

2 Answers2

3

To set up Rating You have to set up two values. Rating and RatingPercent

  • Exif.Image.Rating (18246)
  • Exif.Image.RatingPercent (18249)

These two values are corresponding to each other. So setting just Rating doesn't reflect Rating stars in Windows. (In fact it is very tricky because You set value, You can read it, but in Windows Explorer nothing changes).

 class Program
{
    static void Main(string[] args)
    {
        //0,1,2,3,4,5
        SetRating(0);
        SetRating(1);
        SetRating(2);
        SetRating(3);
        SetRating(4);
        SetRating(5);
    }

    private static void SetRating(short ratingValue)
    {
        short ratingPercentageValue = 0;
        switch (ratingValue)
        {
            case 0: ratingPercentageValue = ratingValue; break;
            case 1: ratingPercentageValue = ratingValue; break;
            default: ratingPercentageValue = (short)((ratingValue - 1) * 25); break;
        }

        string SelectedImage = @"d:\Trash\phototemp\IMG_1200.JPG";
        using (var imageTemp = System.Drawing.Image.FromFile(SelectedImage))
        {
            var rating = imageTemp.PropertyItems.FirstOrDefault(x => x.Id == 18246);
            var ratingPercentage = imageTemp.PropertyItems.FirstOrDefault(x => x.Id == 18249);

            rating.Value = BitConverter.GetBytes(ratingValue);
            rating.Len= rating.Value.Length;
            ratingPercentage.Value = BitConverter.GetBytes(ratingPercentageValue);
            ratingPercentage.Len = ratingPercentage.Value.Length;
            imageTemp.SetPropertyItem(rating);
            imageTemp.SetPropertyItem(ratingPercentage);
            imageTemp.Save(SelectedImage + "new" + ratingValue +".jpg");

        }
    }
}
0

The solution is not optimal (and hackish), but the easiest way is:

1) Use an image on your harddrive. Any image. Just rate it manually, so that the image has this property.

2) This image will work as your "dummy image", so that you can load it in order to call getPropertyItem() on it, to get the property.

3) Once you have the PropertyItem, just change its value, and use SetPropertyItem on your actual image.

    string dummyFileName = @"C:\Users\<youruser>\Pictures\dummy.jpg";
    string realFileName = @"C:\Users\<youruser>\Pictures\real.jpg";
    string realFileNameOutput = @"C:\Users\<youruser\Pictures\real_rated.jpg";

    Image dummyFile = Image.FromFile(dummyFileName);
    var propertyItem = dummyFile.GetPropertyItem(18246);

    Image realImage = Image.FromFile(realFileName);
    realImage.SetPropertyItem(propertyItem);
    realImage.Save(realFileNameOutput);
Terje
  • 1,753
  • 10
  • 13
  • I would love to know why this is downvoted. I know it is hackish, but the real solution will most likely be totally over-engineering such a small problem. Packaging a 1*1 pixel rated image with your application will give you much less troubles than handling different decoders, or diving into the win32 api. – Terje Aug 19 '14 at 12:21
  • Thanks for your help. But i think if i install this app in other computer, still have a "dummy image"... But this is one way at least. Thanks. – user3819845 Aug 19 '14 at 12:45
  • Just add it as a resource to your application like you would add any image or sound resources. Large libraries to fix your challenge probably exists, but without them you're going to need alot of code to solve what should be a simple problem. The .NET api is seriously lacking in this area. – Terje Aug 19 '14 at 12:52
  • i had use `Rate1.jpg` image as image resource... `Image im = Image.FromFile("D:\\2.jpg");` `PropertyItem prop = WindowsFormsApplication2.Properties.Resources.Rate1.GetPropertyItem(18246);` `im.SetPropertyItem(prop);` i checked but nothing gonna change with my "2.jpg". Thanks `@Terje` – user3819845 Aug 19 '14 at 13:44
  • Edited in an example that works for me now @user3819845 - please try the exact example first, and then modify it until it either solves your problem, or breaks. – Terje Aug 20 '14 at 06:58