QuickImage – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.IO;
6 using System.Linq;
7 using System.Runtime.CompilerServices;
8 using System.Threading;
9 using System.Threading.Tasks;
10 using System.Threading.Tasks.Dataflow;
11 using ImageMagick;
12 using ImageMagick.Formats;
13 using QuickImage.Utilities;
14 using Serilog;
15  
16 namespace QuickImage
17 {
18 public class TagManager
19 {
20 private readonly MagickReadSettings _magickReaderSettings;
21 private readonly FileMutex _fileMutex;
22  
23 private TagManager()
24 {
25 _magickReaderSettings = new MagickReadSettings { FrameIndex = 0, FrameCount = 1 };
26 }
27  
28 public TagManager(FileMutex fileMutex) : this()
29 {
30 _fileMutex = fileMutex;
31 }
32  
33 public async Task<bool> StripIptcProfile(string fileName, CancellationToken cancellationToken)
34 {
35 await _fileMutex[fileName].WaitAsync(cancellationToken);
36  
37 try
38 {
39 using var imageCollection = new MagickImageCollection(fileName);
40 using var image = imageCollection[0];
41  
42 var profile = image.GetIptcProfile();
43  
44 if (profile == null)
45 {
46 return true;
47 }
48  
49 image.RemoveProfile(profile);
50 await imageCollection.WriteAsync(fileName, cancellationToken);
51  
52 return true;
53 }
54 catch (Exception exception)
55 {
56 Log.Error(exception, "Could not add keywords.");
57 }
58 finally
59 {
60 _fileMutex[fileName].Release();
61 }
62  
63 return false;
64 }
65  
66 public async Task<bool> AddIptcKeywords(string fileName, IEnumerable<string> keywords,
67 CancellationToken cancellationToken)
68 {
69 await _fileMutex[fileName].WaitAsync(cancellationToken);
70  
71 try
72 {
73 using var imageCollection = new MagickImageCollection(fileName);
74 using var image = imageCollection[0];
75  
76 var profile = image.GetIptcProfile();
77  
78 if (profile == null)
79 {
80 profile = new IptcProfile();
81  
82 foreach (var keyword in keywords)
83 {
84 profile.SetValue(IptcTag.Keyword, keyword);
85 }
86  
87 image.SetProfile(profile);
88 await imageCollection.WriteAsync(fileName, cancellationToken);
89  
90 return true;
91 }
92  
93 var union = keywords.Union(profile.GetAllValues(IptcTag.Keyword).Select(iptcValue => iptcValue.Value),
94 StringComparer.Ordinal).ToList();
95 profile.RemoveValue(IptcTag.Keyword);
96 foreach (var keyword in union)
97 {
98 profile.SetValue(IptcTag.Keyword, keyword);
99 }
100  
101 image.SetProfile(profile);
102 await imageCollection.WriteAsync(fileName, cancellationToken);
103  
104 return true;
105 }
106 catch (Exception exception)
107 {
108 Log.Error(exception, "Could not add keywords.");
109 }
110 finally
111 {
112 _fileMutex[fileName].Release();
113 }
114  
115 return false;
116 }
117  
118 public async Task<bool> RemoveIptcKeywords(string fileName, IEnumerable<string> keywords, CancellationToken cancellationToken)
119 {
120 await _fileMutex[fileName].WaitAsync(cancellationToken);
121  
122 try
123 {
124 using var imageCollection = new MagickImageCollection(fileName);
125 using var image = imageCollection[0];
126  
127 var profile = image.GetIptcProfile();
128  
129 if (profile == null)
130 {
131 return true;
132 }
133  
134 foreach (var keyword in keywords)
135 {
136 profile.RemoveValue(IptcTag.Keyword, keyword);
137 }
138  
139 image.SetProfile(profile);
140 imageCollection.Optimize();
141 await imageCollection.WriteAsync(fileName, cancellationToken);
142  
143 return true;
144 }
145 catch (Exception exception)
146 {
147 Log.Error(exception, "Could not remove keywords.");
148 }
149 finally
150 {
151 _fileMutex[fileName].Release();
152 }
153  
154 return false;
155 }
156  
157 public async IAsyncEnumerable<string> GetIptcKeywords(string fileName, [EnumeratorCancellation] CancellationToken cancellationToken)
158 {
159 await _fileMutex[fileName].WaitAsync(cancellationToken);
160  
161 try
162 {
163 using var imageCollection = new MagickImageCollection(fileName, _magickReaderSettings);
164 using var image = imageCollection[0];
165  
166 var profile = image.GetIptcProfile();
167  
168 if (profile == null)
169 {
170 yield break;
171 }
172  
173 foreach (var keyword in profile.GetAllValues(IptcTag.Keyword))
174 {
175 yield return keyword.Value;
176 }
177 }
178 finally
179 {
180 _fileMutex[fileName].Release();
181 }
182 }
183  
184 public IEnumerable<string> GetIptcKeywords(IMagickImage<ushort> imageFrame)
185 {
186 var profile = imageFrame.GetIptcProfile();
187  
188 if (profile == null)
189 {
190 yield break;
191 }
192  
193 foreach (var keyword in profile.GetAllValues(IptcTag.Keyword))
194 {
195 yield return keyword.Value;
196 }
197  
198 }
199 }
200 }