ImageList半透明,Alpha通道bug处理。

由于ImageList的先天障碍,对alpha通道支持不好。虽然到xp有所改善,但瑕疵依然存在。

通过reflactor发现ImageList通过windows api来进行读写的。写入数据时会对原始图像进行处理,等到读取时已经获取不到原始图像。鉴于此,只能另起炉灶重新编写一个ImageList,也就是缩略图集合类。

思路:

1,应该有缩略图大小属性,由于添加图像后生成缩略图,并与原始图像断绝关系。所以在有缩略图的情况下不允许修改大小。

2,缩略图集合。可增加图像到集合,添加时按指定大小生成缩略图。可通过索引检索以便调用。删除或清空时要释放生成的资源。

好了,以上就是主题思想。下面是代码。

ImageListEx类代码

  1     /// <summary>
  2     /// 缩略图集合
  3     /// </summary>
  4     public sealed partial class ImageListEx : Component
  5     {
  6         private object m_Tag;
  7         /// <summary>
  8         /// 附加数据
  9         /// </summary>
 10         [DefaultValue(null), TypeConverter(typeof(StringConverter))]
 11         public object Tag
 12         {
 13             get
 14             {
 15                 return this.m_Tag;
 16             }
 17             set
 18             {
 19                 this.m_Tag = value;
 20             }
 21         }
 22 
 23         private Size m_Size = new Size(32, 32);
 24         /// <summary>
 25         /// 缩略图大小,只能先设置大小后添加图片
 26         /// </summary>
 27         [DefaultValue(typeof(Size), "32,32")]
 28         public Size ImageSize
 29         {
 30             get
 31             {
 32                 return this.m_Size;
 33             }
 34 
 35             set
 36             {
 37                 if (value.Width <= 0 || value.Height <= 0 || this.ImageThumbs.Count > 0)
 38                     return;
 39 
 40                 this.m_Size = value;
 41             }
 42         }
 43 
 44         private ThumbCollection m_ImageThumbs;
 45         /// <summary>
 46         /// 缩略图,只能先设置大小后添加图片
 47         /// </summary>
 48         [DefaultValue(null), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MergableProperty(false)]
 49         public ThumbCollection ImageThumbs
 50         {
 51             get
 52             {
 53                 if (this.m_ImageThumbs == null)
 54                     this.m_ImageThumbs = new ThumbCollection(this);
 55 
 56                 return this.m_ImageThumbs;
 57             }
 58         }
 59 
 60 
 61         /// <summary>
 62         /// 构造函数
 63         /// </summary>
 64         public ImageListEx()
 65         {
 66         }
 67 
 68         /// <summary>
 69         /// 构造函数
 70         /// </summary>
 71         /// <param name="container">容器</param>
 72         public ImageListEx(IContainer container)
 73         {
 74             container.Add(this);
 75         }
 76 
 77 
 78         /// <summary>
 79         /// 转换为字符串
 80         /// </summary>
 81         /// <returns>字符串</returns>
 82         public override string ToString()
 83         {
 84             string str = base.ToString();
 85             if (this.m_ImageThumbs != null)
 86             {
 87                 return (str + " ImageThumbs.Count: " + this.m_ImageThumbs.Count.ToString(CultureInfo.CurrentCulture) + ", ImageSize: " + this.ImageSize.ToString());
 88             }
 89             return str;
 90         }
 91 
 92         /// <summary>
 93         /// 清理所有正在使用的资源。
 94         /// </summary>
 95         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
 96         protected override void Dispose(bool disposing)
 97         {
 98             if (this.m_ImageThumbs != null)
 99                 this.m_ImageThumbs.Dispose();
100 
101             base.Dispose(disposing);
102         }
103     }
View Code

ImageListEx.ImageInfo类代码

 1     public partial class ImageListEx
 2     {
 3         /// <summary>
 4         /// 图像信息
 5         /// </summary>
 6         public class ImageInfo
 7         {
 8             private string m_Name;
 9             /// <summary>
10             /// 名称说明
11             /// </summary>
12             [DefaultValue(null)]
13             public string Name
14             {
15                 get
16                 {
17                     return this.m_Name;
18                 }
19 
20                 set
21                 {
22                     this.m_Name = value;
23                 }
24             }
25 
26             private Image m_Image;
27             /// <summary>
28             /// 图像
29             /// </summary>
30             [DefaultValue(null)]
31             public Image Image
32             {
33                 get
34                 {
35                     return this.m_Image;
36                 }
37 
38                 set
39                 {
40                     this.m_Image = value;
41                 }
42             }
43 
44             /// <summary>
45             /// 构造函数
46             /// </summary>
47             public ImageInfo()
48             {
49             }
50 
51             /// <summary>
52             /// 构造函数
53             /// </summary>
54             /// <param name="name">名称说明</param>
55             /// <param name="image">图像</param>
56             public ImageInfo(string name, Image image)
57             {
58                 this.m_Name = name;
59                 this.m_Image = image;
60             }
61         }
62     }
View Code

ImageListEx.ThumbCollection类代码

  1     public partial class ImageListEx
  2     {
  3         /// <summary>
  4         /// 缩略图集合
  5         /// </summary>
  6         public class ThumbCollection : IList, ICollection, IEnumerable
  7         {
  8             private ArrayList m_Thumbs;//缩略图
  9             private ImageListEx m_Owner;//父ImageListEx
 10             private bool m_Disposed;//是否已释放资源
 11 
 12 
 13             /// <summary>
 14             /// 数量
 15             /// </summary>
 16             public int Count
 17             {
 18                 get
 19                 {
 20                     return (this.m_Thumbs == null) ? 0 : this.m_Thumbs.Count;
 21                 }
 22             }
 23 
 24             /// <summary>
 25             /// 是否为空
 26             /// </summary>
 27             public bool Empty
 28             {
 29                 get
 30                 {
 31                     return (this.Count == 0);
 32                 }
 33             }
 34 
 35             /// <summary>
 36             /// 是否只读
 37             /// </summary>
 38             public bool IsReadOnly
 39             {
 40                 get
 41                 {
 42                     return false;
 43                 }
 44             }
 45 
 46             /// <summary>
 47             /// 键集合
 48             /// </summary>
 49             public StringCollection Keys
 50             {
 51                 get
 52                 {
 53                     this.CheckDisposed();
 54 
 55                     StringCollection strings = new StringCollection();
 56                     for (int i = 0, length = this.Count; i < length; i++)
 57                     {
 58                         ImageInfo imgInfo = this.m_Thumbs[i] as ImageInfo;
 59                         strings.Add(imgInfo == null ? null : imgInfo.Name);
 60                     }
 61                     return strings;
 62                 }
 63             }
 64 
 65 
 66             /// <summary>
 67             /// 构造函数
 68             /// </summary>
 69             /// <param name="owner">父ImageListEx</param>
 70             public ThumbCollection(ImageListEx owner)
 71             {
 72                 this.m_Thumbs = new ArrayList();
 73                 this.m_Owner = owner;
 74             }
 75 
 76 
 77             //创建缩略图
 78             private ImageInfo CreteThumbInfo(ImageInfo value)
 79             {
 80                 ImageInfo imgInfo = new ImageInfo();
 81                 imgInfo.Name = value.Name;
 82                 if (value != null && this.m_Owner != null)
 83                     imgInfo.Image = ControlPaintEx.StretchImage(value.Image, this.m_Owner.ImageSize);
 84                 return imgInfo;
 85             }
 86 
 87             //检测是否释放
 88             private void CheckDisposed()
 89             {
 90                 if (this.m_Disposed)
 91                     throw (new ObjectDisposedException("m_Thumbs"));
 92             }
 93 
 94             //索引是否在有效范围
 95             private bool IsValidIndex(int index)
 96             {
 97                 return ((index >= 0) && (index < this.Count));
 98             }
 99 
100 
101             #region 自身成员
102 
103             /// <summary>
104             /// 添加图像信息
105             /// </summary>
106             /// <param name="value">图像信息</param>
107             public void Add(ImageInfo value)
108             {
109                 this.CheckDisposed();
110                 this.m_Thumbs.Add(this.CreteThumbInfo(value));
111             }
112 
113             /// <summary>
114             /// 添加图像信息数组
115             /// </summary>
116             /// <param name="values">图像信息数组</param>
117             public void AddRange(ImageInfo[] values)
118             {
119                 this.CheckDisposed();
120                 if (values == null)
121                     throw new ArgumentNullException("values");
122                 foreach (ImageInfo value in values)
123                     this.m_Thumbs.Add(this.CreteThumbInfo(value));
124             }
125 
126             /// <summary>
127             /// 清空所有图像信息并释放其使用的临时资源
128             /// </summary>
129             public void Clear()
130             {
131                 if (this.m_Thumbs != null)
132                 {
133                     for (int i = 0, length = this.Count; i < length; i++)
134                     {
135                         ImageInfo imgInfo = this.m_Thumbs[i] as ImageInfo;
136                         if (imgInfo != null && imgInfo.Image != null)
137                         {
138                             imgInfo.Image.Dispose();
139                             imgInfo.Image = null;
140                             this.m_Thumbs[i] = null;
141                         }
142                     }
143                     this.m_Thumbs.Clear();
144                 }
145             }
146 
147             /// <summary>
148             /// 是否包含指定图像信息
149             /// </summary>
150             /// <param name="value">图像信息</param>
151             /// <returns>包含返回true,否则返回false</returns>
152             [EditorBrowsable(EditorBrowsableState.Never)]
153             public bool Contains(ImageInfo value)
154             {
155                 throw new NotSupportedException();
156             }
157 
158             /// <summary>
159             /// 是否包含指定key
160             /// </summary>
161             /// <param name="key"></param>
162             /// <returns>包含返回true,否则返回false</returns>
163             public bool ContainsKey(string key)
164             {
165                 return this.IsValidIndex(this.IndexOfKey(key));
166             }
167 
168             /// <summary>
169             /// 释放资源
170             /// </summary>
171             public void Dispose()
172             {
173                 if (this.m_Disposed)
174                     return;
175                 this.m_Disposed = true;
176 
177                 this.Clear();
178                 this.m_Thumbs = null;
179             }
180 
181             /// <summary>
182             /// 获取枚举数
183             /// </summary>
184             /// <returns>枚举数</returns>
185             public IEnumerator GetEnumerator()
186             {
187                 this.CheckDisposed();
188                 return this.m_Thumbs.GetEnumerator();
189             }
190 
191             /// <summary>
192             /// 检索指定图像信息
193             /// </summary>
194             /// <param name="value">图像信息</param>
195             /// <returns>图像信息的索引</returns>
196             [EditorBrowsable(EditorBrowsableState.Never)]
197             public int IndexOf(ImageInfo value)
198             {
199                 throw new NotSupportedException();
200             }
201 
202             /// <summary>
203             /// 检索指定key
204             /// </summary>
205             /// <param name="key"></param>
206             /// <returns>键的索引</returns>
207             public int IndexOfKey(string key)
208             {
209                 this.CheckDisposed();
210                 for (int i = 0, length = this.Count; i < length; i++)
211                 {
212                     if ((this.m_Thumbs[i] as ImageInfo).Name == key)
213                         return i;
214                 }
215                 return -1;
216             }
217 
218             /// <summary>
219             /// 移除指定图像信息
220             /// </summary>
221             /// <param name="value">图像信息</param>
222             [EditorBrowsable(EditorBrowsableState.Never)]
223             public void Remove(ImageInfo value)
224             {
225                 throw new NotSupportedException();
226             }
227 
228             /// <summary>
229             /// 移除指定索引的图像信息
230             /// </summary>
231             /// <param name="index">索引</param>
232             public void RemoveAt(int index)
233             {
234                 this.CheckDisposed();
235                 if (this.IsValidIndex(index))
236                     this.m_Thumbs.RemoveAt(index);
237                 else
238                     throw new ArgumentOutOfRangeException("index");
239             }
240 
241             /// <summary>
242             /// 移除指定key的图像信息
243             /// </summary>
244             /// <param name="key"></param>
245             public void RemoveByKey(string key)
246             {
247                 int index = this.IndexOfKey(key);
248                 if (this.IsValidIndex(index))
249                     this.m_Thumbs.RemoveAt(index);
250             }
251 
252             /// <summary>
253             /// 设置指定索引的图像信息的key
254             /// </summary>
255             /// <param name="index">索引</param>
256             /// <param name="key"></param>
257             public void SetKeyName(int index, string key)
258             {
259                 this.CheckDisposed();
260                 if (!this.IsValidIndex(index))
261                     throw new IndexOutOfRangeException();
262                 if (this.m_Thumbs[index] == null)
263                     this.m_Thumbs[index] = new ImageInfo();
264                 (this.m_Thumbs[index] as ImageInfo).Name = key;
265             }
266 
267             /// <summary>
268             /// 获取或设置指定索引的图像信息
269             /// </summary>
270             /// <param name="index">索引</param>
271             /// <returns>图像信息</returns>
272             public ImageInfo this[int index]
273             {
274                 get
275                 {
276                     this.CheckDisposed();
277                     if (!this.IsValidIndex(index))
278                         throw new ArgumentOutOfRangeException("index");
279                     return this.m_Thumbs[index] as ImageInfo;
280                 }
281 
282                 set
283                 {
284                     this.CheckDisposed();
285                     if (!this.IsValidIndex(index))
286                         throw new ArgumentOutOfRangeException("index");
287                     this.m_Thumbs[index] = this.CreteThumbInfo(value);
288                 }
289             }
290 
291             /// <summary>
292             /// 获取指定键的图像信息
293             /// </summary>
294             /// <param name="key"></param>
295             /// <returns>图像信息</returns>
296             public ImageInfo this[string key]
297             {
298                 get
299                 {
300                     this.CheckDisposed();
301                     if ((key != null) && (key.Length > 0))
302                     {
303                         int index = this.IndexOfKey(key);
304                         if (this.IsValidIndex(index))
305                             return this.m_Thumbs[index] as ImageInfo;
306                     }
307                     return null;
308                 }
309             }
310 
311             #endregion
312 
313             #region IList 成员
314 
315             int IList.Add(object value)
316             {
317                 if (!(value is ImageInfo))
318                 {
319                     throw new ArgumentException("BadImageInfo", "value");
320                 }
321                 this.Add((ImageInfo)value);
322                 return (this.Count - 1);
323 
324             }
325 
326             void IList.Clear()
327             {
328                 this.Clear();
329             }
330 
331             bool IList.Contains(object value)
332             {
333                 return ((value is ImageInfo) && this.Contains((ImageInfo)value));
334 
335             }
336 
337             int IList.IndexOf(object value)
338             {
339                 if (value is ImageInfo)
340                     return this.IndexOf((ImageInfo)value);
341                 return -1;
342             }
343 
344             void IList.Insert(int index, object value)
345             {
346                 throw new NotSupportedException();
347             }
348 
349             bool IList.IsFixedSize
350             {
351                 get { return false; }
352             }
353 
354             bool IList.IsReadOnly
355             {
356                 get { return this.IsReadOnly; }
357             }
358 
359             void IList.Remove(object value)
360             {
361                 if (value is ImageInfo)
362                     this.Remove((ImageInfo)value);
363             }
364 
365             void IList.RemoveAt(int index)
366             {
367                 this.RemoveAt(index);
368             }
369 
370             object IList.this[int index]
371             {
372                 get
373                 {
374                     return this[index];
375                 }
376                 set
377                 {
378                     if (!(value is ImageInfo))
379                         throw new ArgumentException("BadImageInfo", "value");
380                     this[index] = (ImageInfo)value;
381                 }
382             }
383 
384             #endregion
385 
386             #region ICollection 成员
387 
388             void ICollection.CopyTo(Array array, int index)
389             {
390                 for (int i = 0, length = this.Count; i < length; i++)
391                     array.SetValue(this.m_Thumbs[i], index++);
392             }
393 
394             int ICollection.Count
395             {
396                 get { return this.Count; }
397             }
398 
399             bool ICollection.IsSynchronized
400             {
401                 get { return false; }
402             }
403 
404             object ICollection.SyncRoot
405             {
406                 get { return this; }
407             }
408 
409             #endregion
410 
411             #region IEnumerable 成员
412 
413             IEnumerator IEnumerable.GetEnumerator()
414             {
415                 return this.GetEnumerator();
416             }
417 
418             #endregion
419         }
420     }
View Code

附图:

通过对比可以明显的发现ImageList的alpha通道bug。红框内为ImageList的图像绘制后的效果,其他的图标为ImageLisEx的图像绘制后的效果。

原文地址:https://www.cnblogs.com/xuchonglei/p/3273603.html