public override String GetUniqueIdentifier(Object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, Boolean useExifOrientation) { var guid = (Guid)key; return(guid.ToString()); }
/// <summary> /// Creates a thumbnail from the given image file. /// </summary> /// <comment> /// This much faster .NET 3.0 method replaces the original .NET 2.0 method. /// The image quality is slightly reduced (low filtering mode). /// </comment> /// <param name="filename">The filename pointing to an image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <returns>The thumbnail image from the given file or null if an error occurs.</returns> public override Image GetThumbnail(string filename, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation) { if (string.IsNullOrEmpty(filename)) { throw new ArgumentException("Filename cannot be empty", "filename"); } if (size.Width <= 0 || size.Height <= 0) { throw new ArgumentException("Thumbnail size cannot be empty.", "size"); } try { using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { // Performance vs image quality settings. // Selecting BitmapCacheOption.None speeds up thumbnail generation of large images tremendously // if the file contains no embedded thumbnail. The image quality is only slightly worse. BitmapFrame frameWpf = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None); return(GetThumbnail(frameWpf, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(frameWpf) : 0)); } } catch { // .Net 2.0 fallback return(base.GetThumbnail(filename, size, useEmbeddedThumbnails, useExifOrientation)); } }
private Image ThumbnailFromEvent(string fileName, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails) { if (useEmbeddedThumbnails == UseEmbeddedThumbnails.Never) { try { Image image = RetrieveImageFromExternaThenFromFile(fileName); return(image); } catch { return(null); } } else { try { RetrieveItemThumbnailEventArgs eRetrieveItemThumbnailEventArgs = new RetrieveItemThumbnailEventArgs(fileName, size); mImageListView.RetrieveItemThumbnailInternal(eRetrieveItemThumbnailEventArgs); //Read from f.ex. Database cache return(eRetrieveItemThumbnailEventArgs.Thumbnail); } catch { return(null); } } }
public override Image GetThumbnail(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { string filePath = key as string; if (!ThumbUtility.CheckThumbnail(filePath)) { Image thumb = null; if (VideoThumbEditor.CheckExtension(filePath)) { thumb = VideoThumbEditor.GetThumb(filePath); } else if (ArchiveThumbEditor.CheckExtension(filePath)) { thumb = ArchiveThumbEditor.GetThumb(filePath); } if (thumb != null) { ThumbUtility.SaveThumbnail(thumb, 0, filePath); return thumb; } return null; } else { return ThumbUtility.LoadThumbnail(filePath); } }
/// <summary> /// Gets the cache state of the specified item. /// </summary> /// <param name="guid">The guid representing the item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public CacheState GetCacheState(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { if (thumbCache.TryGetValue(guid, out CacheItem item) && item != null && item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails && item.AutoRotate == autoRotate && item.UseWIC == useWIC) { return(item.State); } return(CacheState.Unknown); }
/// <summary> /// Initializes a new instance of the <see cref="CacheRequest"/> class /// for use with a virtual item. /// </summary> /// <param name="guid">The guid of the ImageListViewItem.</param> /// <param name="adaptor">The adaptor of this item.</param> /// <param name="key">The public key for the virtual item.</param> /// <param name="size">The size of the requested thumbnail.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="requestType">Type of this request.</param> public CacheRequest(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, RequestType requestType) { Guid = guid; VirtualItemKey = key; Adaptor = adaptor; Size = size; UseEmbeddedThumbnails = useEmbeddedThumbnails; AutoRotate = autoRotate; RequestType = requestType; }
/// <summary> /// Creates a thumbnail from the given image. /// </summary> /// <param name="image">The source image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <returns>The thumbnail image from the given image or null if an error occurs.</returns> public virtual Image GetThumbnail(Image image, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation) { if (size.Width <= 0 || size.Height <= 0) { throw new ArgumentException(); } return(GetThumbnailBmp(image, size, useExifOrientation ? GetRotation(image) : 0)); }
/// <summary> /// Initializes a new instance of the <see cref="CacheItem"/> class /// for use with a virtual item. /// </summary> /// <param name="guid">The guid of the ImageListViewItem.</param> /// <param name="size">The size of the requested thumbnail.</param> /// <param name="image">The thumbnail image.</param> /// <param name="state">The cache state of the item.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> public CacheItem(Guid guid, Size size, Image image, CacheState state, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate) { Guid = guid; Size = size; Image = image; State = state; UseEmbeddedThumbnails = useEmbeddedThumbnails; AutoRotate = autoRotate; disposed = false; }
public override Image GetThumbnail(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation) { if (disposed) { return(null); } File file = (File)key; return(getThumbnailFromFile(file)); }
/// <summary> /// Returns the thumbnail image for the given item. /// </summary> /// <param name="key">Item key.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>The thumbnail image from the given item or null if an error occurs.</returns> public override Image GetThumbnail(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { if (disposed) return null; string filename = (string)key; if (File.Exists(filename)) return ThumbnailExtractor.FromFile(filename, size, useEmbeddedThumbnails, useExifOrientation, useWIC); else return null; }
/// <summary> /// Gets the image from the gallery cache. If the image is not cached, /// null will be returned. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> public Image GetGalleryImage(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate) { if (galleryItem != null && galleryItem.Guid == guid && galleryItem.Image != null && galleryItem.Size == thumbSize && galleryItem.UseEmbeddedThumbnails == useEmbeddedThumbnails && galleryItem.AutoRotate == autoRotate) { return(galleryItem.Image); } else { return(null); } }
/// <summary> /// Gets the image from the thumbnail cache. If the image is not cached, /// null will be returned. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> /// <param name="clone">true to return a clone of the cached image; otherwise false.</param> public Image GetImage(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC, bool clone) { CacheItem item = null; if (thumbCache.TryGetValue(guid, out item) && item != null && item.Image != null && item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails && item.AutoRotate == autoRotate && item.UseWIC == useWIC) { return(clone ? (Image)item.Image.Clone() : item.Image); } else { return(null); } }
public override Image GetThumbnail(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { string file = key as string; if (!string.IsNullOrEmpty(file)) { using (Image img = Image.FromFile(file)) { Bitmap thumb = new Bitmap(img, size); return thumb; } } return null; }
/// <summary> /// Creates a thumbnail from the given image. /// </summary> /// <param name="image">The source image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <returns>The thumbnail image from the given image or null if an error occurs.</returns> public override Image GetThumbnail(Image image, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation) { if (size.Width <= 0 || size.Height <= 0) { throw new ArgumentException(); } MemoryStream stream = null; BitmapFrame frameWpf = null; try { stream = new MemoryStream(); image.Save(stream, ImageFormat.Bmp); // Performance vs image quality settings. // Selecting BitmapCacheOption.None speeds up thumbnail generation of large images tremendously // if the file contains no embedded thumbnail. The image quality is only slightly worse. stream.Seek(0, SeekOrigin.Begin); frameWpf = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None); } catch { if (stream != null) { stream.Dispose(); stream = null; } frameWpf = null; } if (stream == null || frameWpf == null) { if (stream != null) { stream.Dispose(); stream = null; } // .Net 2.0 fallback return(base.GetThumbnail(image, size, useEmbeddedThumbnails, useExifOrientation)); } Image thumb = GetThumbnail(frameWpf, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(frameWpf) : 0); stream.Dispose(); return(thumb); }
/// <summary> /// Creates a thumbnail from the given image file. /// </summary> /// <param name="filename">The filename pointing to an image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <returns>The thumbnail image from the given file or null if an error occurs.</returns> public virtual Image GetThumbnail(string filename, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation) { if (string.IsNullOrEmpty(filename)) { throw new ArgumentException("Filename cannot be empty", "filename"); } if (size.Width <= 0 || size.Height <= 0) { throw new ArgumentException("Thumbnail size cannot be empty.", "size"); } return(GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0)); }
/// <summary> /// Returns a unique identifier for this thumbnail to be used in persistent /// caching. /// </summary> /// <param name="key">Item key.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <returns>A unique identifier string for the thumnail.</returns> public override string GetUniqueIdentifier(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation) { StringBuilder sb = new StringBuilder(); sb.Append((string)key); // Filename sb.Append(':'); sb.Append(size.Width); // Thumbnail size sb.Append(','); sb.Append(size.Height); sb.Append(':'); sb.Append(useEmbeddedThumbnails); sb.Append(':'); sb.Append(useExifOrientation); return(sb.ToString()); }
/// <summary> /// Creates a thumbnail from the given image file. /// </summary> /// <comment> /// This much faster .NET 3.0 method replaces the original .NET 2.0 method. /// The image quality is slightly reduced (low filtering mode). /// </comment> /// <param name="filename">The filename pointing to an image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>The thumbnail image from the given file or null if an error occurs.</returns> public static Image FromFile(string filename, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { if (string.IsNullOrEmpty(filename)) { throw new ArgumentException("Filename cannot be empty", "filename"); } if (size.Width <= 0 || size.Height <= 0) { throw new ArgumentException("Thumbnail size cannot be empty.", "size"); } if (useWIC) { #if USEWIC try { using (Stream stream = GetImageStream(filename)) { // Performance vs image quality settings. // Selecting BitmapCacheOption.None speeds up thumbnail generation of large images tremendously // if the file contains no embedded thumbnail. The image quality is only slightly worse. BitmapFrame frameWpf = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None); return(GetThumbnail(frameWpf, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(frameWpf) : 0)); } } catch { // .Net 2.0 fallback return(GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0)); } #else // .Net 2.0 fallback return(GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0)); #endif } else { // .Net 2.0 fallback return(GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0)); } }
/// <summary> /// Returns a unique identifier for this thumbnail to be used in persistent /// caching. /// </summary> /// <param name="key">Item key.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>A unique identifier string for the thumnail.</returns> public override string GetUniqueIdentifier(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { StringBuilder sb = new StringBuilder(); sb.Append((string)key);// Filename sb.Append(':'); sb.Append(size.Width); // Thumbnail size sb.Append(','); sb.Append(size.Height); sb.Append(':'); sb.Append(useEmbeddedThumbnails); sb.Append(':'); sb.Append(useExifOrientation); sb.Append(':'); sb.Append(useWIC); return sb.ToString(); }
/// <summary> /// Creates a thumbnail from the given image file. /// </summary> /// <comment> /// This much faster .NET 3.0 method replaces the original .NET 2.0 method. /// The image quality is slightly reduced (low filtering mode). /// </comment> /// <param name="filename">The filename pointing to an image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>The thumbnail image from the given file or null if an error occurs.</returns> public static Image FromFile(string filename, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { if (string.IsNullOrEmpty(filename)) throw new ArgumentException("Filename cannot be empty", "filename"); if (size.Width <= 0 || size.Height <= 0) throw new ArgumentException("Thumbnail size cannot be empty.", "size"); if (useWIC) { #if USEWIC try { using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { // Performance vs image quality settings. // Selecting BitmapCacheOption.None speeds up thumbnail generation of large images tremendously // if the file contains no embedded thumbnail. The image quality is only slightly worse. BitmapFrame frameWpf = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None); return GetThumbnail(frameWpf, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(frameWpf) : 0); } } catch { // .Net 2.0 fallback return GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0); } #else // .Net 2.0 fallback return GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0); #endif } else { // .Net 2.0 fallback return GetThumbnailBmp(filename, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(filename) : 0); } }
/// <summary> /// Adds the virtual item image to the renderer cache queue. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="adaptor">The adaptor of this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public void AddToRendererCache(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { // Already cached? if (rendererItem != null && rendererItem.Guid == guid && rendererItem.Image != null && rendererItem.Size == thumbSize && rendererItem.UseEmbeddedThumbnails == useEmbeddedThumbnails && rendererItem.AutoRotate == autoRotate && rendererItem.UseWIC == useWIC) return; // Add to cache queue RunWorker(new CacheRequest(guid, adaptor, key, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC, RequestType.Renderer), 1); }
/// <summary> /// Adds a virtual item to the cache. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="adaptor">The adaptor for this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="thumb">Thumbnail image to add to cache.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public void Add(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size thumbSize, Image thumb, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { // Already cached? CacheItem item = null; if (thumbCache.TryGetValue(guid, out item)) { if (item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails) return; } // Resize only when thumb is too large in size if (thumb.Width > thumbSize.Width || thumb.Height > thumbSize.Height) { thumb = ThumbnailExtractor.FromImage(thumb, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC); } // Add to cache thumbCache.Add(guid, new CacheItem(guid, thumbSize, thumb, 0, CacheState.Cached, useEmbeddedThumbnails, autoRotate, useWIC)); // Add to disk cache //using (MemoryStream stream = new MemoryStream()) //{ // string diskCacheKey = adaptor.GetUniqueIdentifier(key, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC); // thumb.Save(stream, System.Drawing.Imaging.ImageFormat.Png); // diskCache.Write(diskCacheKey, stream); //} // Raise the cache events if (mImageListView != null) { mImageListView.OnThumbnailCachedInternal(guid, thumb, thumbSize, true); mImageListView.Refresh(); } }
/// <summary> /// Adds a virtual item to the cache queue. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="adaptor">he adaptor for this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public void Add(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { // Already cached? CacheItem item = null; if (thumbCache.TryGetValue(guid, out item)) { if (item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails) return; } // Add to cache queue RunWorker(new CacheRequest(guid, adaptor, key, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC, RequestType.Thumbnail)); }
/// <summary> /// Adds a virtual item to the cache queue. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> public void Add(Guid guid, object key, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails) { lock (lockObject) { // Already cached? CacheItem item = null; if (thumbCache.TryGetValue(guid, out item)) { if (item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails) return; else { item.Dispose(); thumbCache.Remove(guid); } } // Add to cache toCache.Push(new CacheItem(guid, key, thumbSize, null, CacheState.Unknown, useEmbeddedThumbnails)); Monitor.Pulse(lockObject); } }
/// <summary> /// Creates a thumbnail from the given image file. /// </summary> /// <param name="filename">The filename pointing to an image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="rotate">Rotation angle.</param> /// <returns>The image from the given file or null if an error occurs.</returns> internal static Image GetThumbnailBmp(string filename, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, int rotate) { if (size.Width <= 0 || size.Height <= 0) throw new ArgumentException(); // Check if this is an image file try { using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { if (!Utility.IsImage(stream)) return null; } } catch { return null; } Image source = null; Image thumb = null; // Try to read the exif thumbnail if (useEmbeddedThumbnails != UseEmbeddedThumbnails.Never) { try { using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { using (Image img = Image.FromStream(stream, false, false)) { foreach (int index in img.PropertyIdList) { if (index == TagThumbnailData) { // Fetch the embedded thumbnail byte[] rawImage = img.GetPropertyItem(TagThumbnailData).Value; using (MemoryStream memStream = new MemoryStream(rawImage)) { source = Image.FromStream(memStream); } if (useEmbeddedThumbnails == UseEmbeddedThumbnails.Auto) { // Check that the embedded thumbnail is large enough. if (Math.Max((float)source.Width / (float)size.Width, (float)source.Height / (float)size.Height) < 1.0f) { source.Dispose(); source = null; } } break; } } } } } catch { if (source != null) source.Dispose(); source = null; } } // Fix for the missing semicolon in GIF files MemoryStream streamCopy = null; try { if (source == null) { using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { byte[] gifSignature = new byte[4]; stream.Read(gifSignature, 0, 4); if (Encoding.ASCII.GetString(gifSignature) == "GIF8") { stream.Seek(0, SeekOrigin.Begin); streamCopy = new MemoryStream(); byte[] buffer = new byte[32768]; int read = 0; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { streamCopy.Write(buffer, 0, read); } // Append the missing semicolon streamCopy.Seek(-1, SeekOrigin.End); if (streamCopy.ReadByte() != 0x3b) streamCopy.WriteByte(0x3b); source = Image.FromStream(streamCopy); } } } } catch { if (source != null) source.Dispose(); source = null; if (streamCopy != null) streamCopy.Dispose(); streamCopy = null; } // Revert to source image if an embedded thumbnail of required size // was not found. FileStream sourceStream = null; if (source == null) { try { sourceStream = new FileStream(filename, FileMode.Open, FileAccess.Read); source = Image.FromStream(sourceStream); } catch { if (source != null) source.Dispose(); if (sourceStream != null) sourceStream.Dispose(); source = null; sourceStream = null; } } // If all failed, return null. if (source == null) return null; // Create the thumbnail try { double scale; if (rotate % 180 != 0) { scale = Math.Min(size.Height / (double)source.Width, size.Width / (double)source.Height); } else { scale = Math.Min(size.Width / (double)source.Width, size.Height / (double)source.Height); } thumb = ScaleDownRotateBitmap(source, scale, rotate); } catch { if (thumb != null) thumb.Dispose(); thumb = null; } finally { if (source != null) source.Dispose(); source = null; if (sourceStream != null) sourceStream.Dispose(); sourceStream = null; if (streamCopy != null) streamCopy.Dispose(); streamCopy = null; } return thumb; }
/// <summary> /// Gets the cache state of the specified item. /// </summary> /// <param name="guid">The guid representing the item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public CacheState GetCacheState(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { CacheItem item = null; if (thumbCache.TryGetValue(guid, out item) && item != null && item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails && item.AutoRotate == autoRotate && item.UseWIC == useWIC) return item.State; return CacheState.Unknown; }
/// <summary> /// Returns a unique identifier for this thumbnail to be used in persistent /// caching. /// </summary> /// <param name="key">Item key.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>A unique identifier string for the thumnail.</returns> public abstract string GetUniqueIdentifier(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC);
/// <summary> /// Initializes a new instance of the CacheItem class. /// </summary> /// <param name="guid">The guid of the ImageListViewItem.</param> /// <param name="filename">The file system path to the image file.</param> /// <param name="size">The size of the requested thumbnail.</param> /// <param name="image">The thumbnail image.</param> /// <param name="state">The cache state of the item.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> public CacheItem(Guid guid, string filename, Size size, Image image, CacheState state, UseEmbeddedThumbnails useEmbeddedThumbnails) { mGuid = guid; mFileName = filename; mSize = size; mImage = image; mState = state; mUseEmbeddedThumbnails = useEmbeddedThumbnails; mIsVirtualItem = false; disposed = false; }
public override string GetUniqueIdentifier(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { return (string)key; }
/// <summary> /// Adds the virtual item image to the renderer cache queue. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> public void AddToRendererCache(Guid guid, object key, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails) { lock (lockObject) { // Already cached? if (rendererGuid == guid && rendererItem != null && rendererItem.Size == thumbSize && rendererItem.UseEmbeddedThumbnails == useEmbeddedThumbnails) return; // Renderer cache holds one item only. rendererToCache.Clear(); rendererToCache.Push(new CacheItem(guid, key, thumbSize, null, CacheState.Unknown, useEmbeddedThumbnails)); Monitor.Pulse(lockObject); } }
/// <summary> /// Adds a virtual item to the cache. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="thumb">Thumbnail image to add to cache.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> public void Add(Guid guid, object key, Size thumbSize, Image thumb, UseEmbeddedThumbnails useEmbeddedThumbnails) { lock (lockObject) { // Already cached? CacheItem item = null; if (thumbCache.TryGetValue(guid, out item)) { if (item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails) return; else { item.Dispose(); thumbCache.Remove(guid); } } // Add to cache thumbCache.Add(guid, new CacheItem(guid, key, thumbSize, thumb, CacheState.Cached, useEmbeddedThumbnails)); } try { if (mImageListView != null && mImageListView.IsHandleCreated && !mImageListView.IsDisposed) { mImageListView.Invoke(new ThumbnailCachedEventHandlerInternal( mImageListView.OnThumbnailCachedInternal), guid, false); mImageListView.Invoke(new RefreshDelegateInternal( mImageListView.OnRefreshInternal)); } } catch (ObjectDisposedException) { if (!Stopping) throw; } catch (InvalidOperationException) { if (!Stopping) throw; } }
/// <summary> /// Gets the image from the gallery cache. If the image is not cached, /// null will be returned. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public Image GetGalleryImage(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { if (galleryItem != null && galleryItem.Guid == guid && galleryItem.Image != null && galleryItem.Size == thumbSize && galleryItem.UseEmbeddedThumbnails == useEmbeddedThumbnails && galleryItem.AutoRotate == autoRotate && galleryItem.UseWIC == useWIC) return galleryItem.Image; else return null; }
/// <summary> /// Returns the thumbnail image for the given item. /// </summary> /// <param name="key">Item key.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>The thumbnail image from the given item or null if an error occurs.</returns> public override Image GetThumbnail(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { if (disposed) return null; string uri = (string)key; try { using (WebClient client = new WebClient()) { byte[] imageData = client.DownloadData(uri); using (MemoryStream stream = new MemoryStream(imageData)) { using (Image sourceImage = Image.FromStream(stream)) { return ThumbnailExtractor.FromImage(sourceImage, size, useEmbeddedThumbnails, useExifOrientation, useWIC); } } } } catch { return null; } }
/// <summary> /// Gets the image from the thumbnail cache. If the image is not cached, /// null will be returned. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> /// <param name="clone">true to return a clone of the cached image; otherwise false.</param> public Image GetImage(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC, bool clone) { CacheItem item = null; if (thumbCache.TryGetValue(guid, out item) && item != null && item.Image != null && item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails && item.AutoRotate == autoRotate && item.UseWIC == useWIC) return clone ? (Image)item.Image.Clone() : item.Image; else return null; }
/// <summary> /// Returns the thumbnail image for the given item. /// </summary> /// <param name="key">Item key.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>The thumbnail image from the given item or null if an error occurs.</returns> public abstract Image GetThumbnail(object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC);
/// <summary> /// Creates a thumbnail from the given image. /// </summary> /// <param name="image">The source image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="useExifOrientation">true to automatically rotate images based on Exif orientation; otherwise false.</param> /// <param name="useWIC">true to use Windows Imaging Component; otherwise false.</param> /// <returns>The thumbnail image from the given image or null if an error occurs.</returns> public static Image FromImage(Image image, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool useExifOrientation, bool useWIC) { if (size.Width <= 0 || size.Height <= 0) throw new ArgumentException(); if (useWIC) { #if USEWIC MemoryStream stream = null; BitmapFrame frameWpf = null; try { stream = new MemoryStream(); image.Save(stream, ImageFormat.Bmp); // Performance vs image quality settings. // Selecting BitmapCacheOption.None speeds up thumbnail generation of large images tremendously // if the file contains no embedded thumbnail. The image quality is only slightly worse. stream.Seek(0, SeekOrigin.Begin); frameWpf = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None); } catch { if (stream != null) { stream.Dispose(); stream = null; } frameWpf = null; } if (stream == null || frameWpf == null) { if (stream != null) { stream.Dispose(); stream = null; } // .Net 2.0 fallback Image img = GetThumbnailBmp(image, size, useExifOrientation ? GetRotation(image) : 0); return img; } Image thumb = GetThumbnail(frameWpf, size, useEmbeddedThumbnails, useExifOrientation ? GetRotation(frameWpf) : 0); stream.Dispose(); return thumb; #else // .Net 2.0 fallback return GetThumbnailBmp(image, size, useExifOrientation ? GetRotation(image) : 0); #endif } else { // .Net 2.0 fallback return GetThumbnailBmp(image, size, useExifOrientation ? GetRotation(image) : 0); } }
/// <summary> /// Initializes a new instance of the <see cref="CacheRequest"/> class /// for use with a virtual item. /// </summary> /// <param name="guid">The guid of the ImageListViewItem.</param> /// <param name="adaptor">The adaptor of this item.</param> /// <param name="key">The public key for the virtual item.</param> /// <param name="size">The size of the requested thumbnail.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> /// <param name="requestType">Type of this request.</param> public CacheRequest(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC, RequestType requestType) { Guid = guid; VirtualItemKey = key; Adaptor = adaptor; Size = size; UseEmbeddedThumbnails = useEmbeddedThumbnails; AutoRotate = autoRotate; UseWIC = useWIC; RequestType = requestType; }
/// <summary> /// Creates a thumbnail from the given bitmap. /// </summary> /// <param name="bmp">Source bitmap.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <param name="rotate">Rotation angle in degrees.</param> private static Image GetThumbnail(BitmapFrame bmp, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails, int rotate) { Image thumb = null; // Try to read the thumbnail. if (bmp.Thumbnail != null) { try { BitmapSource sourceWpf = bmp.Thumbnail; double scale; if (rotate % 180 != 0) { scale = Math.Min(size.Height / (double)sourceWpf.PixelWidth, size.Width / (double)sourceWpf.PixelHeight); } else { scale = Math.Min(size.Width / (double)sourceWpf.PixelWidth, size.Height / (double)sourceWpf.PixelHeight); } if (bmp.Decoder == null || (bmp.Decoder.Preview == null && bmp.Decoder.Frames == null) || useEmbeddedThumbnails == UseEmbeddedThumbnails.Always) { // Take the thumbnail if nothing else is available or if ALWAYS thumb = ConvertToBitmap(ScaleDownRotateBitmap(sourceWpf, scale, rotate)); } else if (useEmbeddedThumbnails == UseEmbeddedThumbnails.Auto) { // Check that the embedded thumbnail is large enough. if ((float)scale <= 1.0f) { thumb = ConvertToBitmap(ScaleDownRotateBitmap(sourceWpf, scale, rotate)); } } } catch { if (thumb != null) { thumb.Dispose(); thumb = null; } } } // Try to read the preview. if (bmp.Decoder != null && bmp.Decoder.Preview != null && thumb == null) { try { BitmapSource sourceWpf = bmp.Decoder.Preview; double scale; if (rotate % 180 != 0) { scale = Math.Min(size.Height / (double)sourceWpf.PixelWidth, size.Width / (double)sourceWpf.PixelHeight); } else { scale = Math.Min(size.Width / (double)sourceWpf.PixelWidth, size.Height / (double)sourceWpf.PixelHeight); } if (bmp.Decoder.Frames == null || useEmbeddedThumbnails == UseEmbeddedThumbnails.Always) { // Take the thumbnail if nothing else is available or if ALWAYS thumb = ConvertToBitmap(ScaleDownRotateBitmap(sourceWpf, scale, rotate)); } else if (useEmbeddedThumbnails == UseEmbeddedThumbnails.Auto) { // Check that the embedded thumbnail is large enough. if ((float)scale <= 1.0f) { thumb = ConvertToBitmap(ScaleDownRotateBitmap(sourceWpf, scale, rotate)); } } } catch { if (thumb != null) { thumb.Dispose(); thumb = null; } } } // Use source image if nothings else fits. if (bmp.Decoder != null && bmp.Decoder.Frames != null && thumb == null) { try { BitmapSource sourceWpf = bmp.Decoder.Frames[0]; double scale; if (rotate % 180 != 0) { scale = Math.Min(size.Height / (double)sourceWpf.PixelWidth, size.Width / (double)sourceWpf.PixelHeight); } else { scale = Math.Min(size.Width / (double)sourceWpf.PixelWidth, size.Height / (double)sourceWpf.PixelHeight); } thumb = ConvertToBitmap(ScaleDownRotateBitmap(sourceWpf, scale, rotate)); } catch { if (thumb != null) { thumb.Dispose(); thumb = null; } } } return thumb; }
/// <summary> /// Initializes a new instance of the <see cref="CacheItem"/> class /// for use with a virtual item. /// </summary> /// <param name="guid">The guid of the ImageListViewItem.</param> /// <param name="size">The size of the requested thumbnail.</param> /// <param name="image">The thumbnail image.</param> /// <param name="rating">The rating of the item.</param> /// <param name="state">The cache state of the item.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public CacheItem(Guid guid, Size size, Image image, ushort rating, CacheState state, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { Guid = guid; Size = size; Image = image; Rating = rating; State = state; UseEmbeddedThumbnails = useEmbeddedThumbnails; AutoRotate = autoRotate; UseWIC = useWIC; disposed = false; }
/// <summary> /// Initializes a new instance of the ImageListView class. /// </summary> public ImageListView() { mColors = new ImageListViewColor(); SetRenderer(new ImageListViewRenderer()); AllowColumnClick = true; AllowColumnResize = true; AllowDrag = false; AllowDuplicateFileNames = false; AllowPaneResize = true; mBorderStyle = BorderStyle.Fixed3D; mCacheMode = CacheMode.OnDemand; mCacheLimitAsItemCount = 0; mCacheLimitAsMemory = 20 * 1024 * 1024; mColumns = new ImageListViewColumnHeaderCollection(this); ResourceManager manager = new ResourceManager("Manina.Windows.Forms.ImageListViewResources", Assembly.GetExecutingAssembly()); mDefaultImage = manager.GetObject("DefaultImage") as Image; mErrorImage = manager.GetObject("ErrorImage") as Image; HeaderFont = this.Font; mItems = new ImageListViewItemCollection(this); MultiSelect = true; mPaneWidth = 240; mRetryOnError = true; mSelectedItems = new ImageListViewSelectedItemCollection(this); mCheckedItems = new ImageListViewCheckedItemCollection(this); mSortColumn = ColumnType.Name; mSortOrder = SortOrder.None; SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.Selectable | ControlStyles.UserMouse, true); ScrollBars = true; mShowCheckBoxes = false; mCheckBoxAlignment = ContentAlignment.BottomRight; mCheckBoxPadding = new Size(2, 2); mShowFileIcons = false; mIconAlignment = ContentAlignment.TopRight; mIconPadding = new Size(2, 2); Text = string.Empty; mThumbnailSize = new Size(96, 96); mUseEmbeddedThumbnails = UseEmbeddedThumbnails.Auto; mView = View.Thumbnails; mViewOffset = new Point(0, 0); hScrollBar = new HScrollBar(); vScrollBar = new VScrollBar(); hScrollBar.Visible = false; vScrollBar.Visible = false; hScrollBar.Scroll += new ScrollEventHandler(hScrollBar_Scroll); vScrollBar.Scroll += new ScrollEventHandler(vScrollBar_Scroll); layoutManager = new ImageListViewLayoutManager(this); forceRefresh = false; navigationManager = new ImageListViewNavigationManager(this); cacheManager = new ImageListViewCacheManager(this); itemCacheManager = new ImageListViewItemCacheManager(this); disposed = false; }
/// <summary> /// Adds a virtual item to the cache. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="adaptor">The adaptor for this item.</param> /// <param name="key">The key of this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="thumb">Thumbnail image to add to cache.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> /// <param name="autoRotate">AutoRotate property of the owner control.</param> /// <param name="useWIC">Whether to use WIC.</param> public void Add(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size thumbSize, Image thumb, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC) { // Already cached? CacheItem item = null; if (thumbCache.TryGetValue(guid, out item)) { if (item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails) return; } // Add to cache thumbCache.Add(guid, new CacheItem(guid, thumbSize, ThumbnailExtractor.FromImage(thumb, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC), CacheState.Cached, useEmbeddedThumbnails, autoRotate, useWIC)); // Raise the cache events if (mImageListView != null) { mImageListView.OnThumbnailCachedInternal(guid, thumb, thumbSize, true); mImageListView.Refresh(); } }
/// <summary> /// Gets the image from the renderer cache. If the image is not cached, /// null will be returned. /// </summary> /// <param name="guid">The guid representing this item.</param> /// <param name="thumbSize">Requested thumbnail size.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> public Image GetRendererImage(Guid guid, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails) { lock (lockObject) { if (rendererGuid == guid && rendererItem != null && rendererItem.Size == thumbSize && rendererItem.UseEmbeddedThumbnails == useEmbeddedThumbnails) return rendererItem.Image; } return null; }
/// <summary> /// Creates a thumbnail from the given image file. /// </summary> /// <param name="filename">The filename pointing to an image.</param> /// <param name="size">Requested image size.</param> /// <param name="useEmbeddedThumbnails">Embedded thumbnail usage.</param> /// <returns>The image from the given file or null if an error occurs.</returns> internal static Image ThumbnailFromFile(string filename, Size size, UseEmbeddedThumbnails useEmbeddedThumbnails) { if (size.Width <= 0 || size.Height <= 0) throw new ArgumentException(); Image source = null; Image thumb = null; // Try to read the exif thumbnail if (useEmbeddedThumbnails != UseEmbeddedThumbnails.Never) { try { using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { using (Image img = Image.FromStream(stream, false, false)) { foreach (int index in img.PropertyIdList) { if (index == PropertyTagThumbnailData) { // Fetch the embedded thumbnail byte[] rawImage = img.GetPropertyItem(PropertyTagThumbnailData).Value; using (MemoryStream memStream = new MemoryStream(rawImage)) { source = Image.FromStream(memStream); } if (useEmbeddedThumbnails == UseEmbeddedThumbnails.Auto) { // Check that the embedded thumbnail is large enough. if (Math.Max((float)source.Width / (float)size.Width, (float)source.Height / (float)size.Height) < 1.0f) { source.Dispose(); source = null; } } break; } } } } } catch { if (source != null) source.Dispose(); source = null; } } // Fix for the missing semicolon in GIF files MemoryStream streamCopy = null; try { if (source == null) { using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { byte[] gifSignature = new byte[6]; stream.Read(gifSignature, 0, 6); if (Encoding.ASCII.GetString(gifSignature) == "GIF89a") { stream.Seek(0, SeekOrigin.Begin); streamCopy = new MemoryStream(); byte[] buffer = new byte[32768]; int read = 0; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { streamCopy.Write(buffer, 0, read); } // Append the mising semicolon streamCopy.Seek(-1, SeekOrigin.End); if (streamCopy.ReadByte() != 0x3b) streamCopy.WriteByte(0x3b); source = Image.FromStream(streamCopy); } } } } catch { if (source != null) source.Dispose(); source = null; if (streamCopy != null) streamCopy.Dispose(); streamCopy = null; } // Revert to source image if an embedded thumbnail of required size // was not found. FileStream sourceStream = null; if (source == null) { try { sourceStream = new FileStream(filename, FileMode.Open, FileAccess.Read); source = Image.FromStream(sourceStream); } catch { if (source != null) source.Dispose(); if (sourceStream != null) sourceStream.Dispose(); source = null; sourceStream = null; } } // If all failed, return null. if (source == null) return null; // Create the thumbnail try { Size scaled = GetSizedImageBounds(source, size); thumb = new Bitmap(source, scaled.Width, scaled.Height); using (Graphics g = Graphics.FromImage(thumb)) { g.PixelOffsetMode = PixelOffsetMode.None; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.Clear(Color.Transparent); g.DrawImage(source, 0, 0, scaled.Width, scaled.Height); } } catch { if (thumb != null) thumb.Dispose(); thumb = null; } finally { if (source != null) source.Dispose(); source = null; if (sourceStream != null) sourceStream.Dispose(); sourceStream = null; if (streamCopy != null) streamCopy.Dispose(); streamCopy = null; } return thumb; }
/// <summary> /// Initializes a new instance of the ImageListView class. /// </summary> public ImageListView() { // Renderer parameters controlSuspended = false; rendererSuspendCount = 0; rendererNeedsPaint = true; mColors = ImageListViewColor.Default; Renderer = new ImageListViewRenderer(); // Property defaults AutoRotateThumbnails = true; AllowCheckBoxClick = true; AllowColumnClick = true; AllowColumnResize = true; AllowDrag = false; AllowDuplicateFileNames = false; AllowPaneResize = true; mBorderStyle = BorderStyle.Fixed3D; mCacheMode = CacheMode.OnDemand; mCacheLimitAsItemCount = 0; mCacheLimitAsMemory = 20 * 1024 * 1024; mColumns = new ImageListViewColumnHeaderCollection(this); resources = new ResourceManager("Manina.Windows.Forms.ImageListViewResources", typeof(ImageListView).Assembly); mDefaultImage = resources.GetObject("DefaultImage") as Image; mErrorImage = resources.GetObject("ErrorImage") as Image; mRatingImage = resources.GetObject("RatingImage") as Image; mEmptyRatingImage = resources.GetObject("EmptyRatingImage") as Image; GroupHeaderFont = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold); ColumnHeaderFont = new Font("Microsoft Sans Serif", 8.25f); mIntegralScroll = false; mItems = new ImageListViewItemCollection(this); MultiSelect = true; mPaneWidth = 240; mRetryOnError = true; mSelectedItems = new ImageListViewSelectedItemCollection(this); mCheckedItems = new ImageListViewCheckedItemCollection(this); mSortColumn = 0; mGroupColumn = 0; mSortOrder = SortOrder.None; mGroupOrder = SortOrder.None; SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.Selectable | ControlStyles.UserMouse, true); ScrollBars = true; ShellIconFallback = true; ShellIconFromFileContent = true; Size = new Size(120, 100); mShowCheckBoxes = false; mCheckBoxAlignment = ContentAlignment.BottomRight; mCheckBoxPadding = new Size(2, 2); mShowFileIcons = false; mIconAlignment = ContentAlignment.TopRight; mIconPadding = new Size(2, 2); Text = string.Empty; mThumbnailSize = new Size(96, 96); mUseEmbeddedThumbnails = UseEmbeddedThumbnails.Auto; mUseWIC = UseWIC.Auto; mView = View.Thumbnails; mViewOffset = new Point(0, 0); mShowScrollBars = true; // Child controls hScrollBar = new HScrollBar(); vScrollBar = new VScrollBar(); hScrollBar.Visible = false; vScrollBar.Visible = false; hScrollBar.Scroll += hScrollBar_Scroll; vScrollBar.Scroll += vScrollBar_Scroll; Controls.Add(hScrollBar); Controls.Add(vScrollBar); // Groups groups = new ImageListViewGroupCollection(this); showGroups = false; // Lazy refresh timer lazyRefreshTimer = new System.Timers.Timer(); lazyRefreshTimer.Interval = ImageListViewRenderer.LazyRefreshInterval; lazyRefreshTimer.Enabled = false; lazyRefreshTimer.Elapsed += lazyRefreshTimer_Tick; lazyRefreshCallback = new RefreshDelegateInternal(Refresh); // Helpers layoutManager = new ImageListViewLayoutManager(this); navigationManager = new ImageListViewNavigationManager(this); // Cache nabagers defaultAdaptor = new ImageListViewItemAdaptors.FileSystemAdaptor(); thumbnailCache = new ImageListViewCacheThumbnail(this); shellInfoCache = new ImageListViewCacheShellInfo(this); metadataCache = new ImageListViewCacheMetadata(this); disposed = false; }
/// <summary> /// Initializes a new instance of the CacheItem class /// for use with a virtual item. /// </summary> /// <param name="guid">The guid of the ImageListViewItem.</param> /// <param name="key">The public key for the virtual item.</param> /// <param name="size">The size of the requested thumbnail.</param> /// <param name="image">The thumbnail image.</param> /// <param name="state">The cache state of the item.</param> /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param> public CacheItem(Guid guid, object key, Size size, Image image, CacheState state, UseEmbeddedThumbnails useEmbeddedThumbnails) { mGuid = guid; mVirtualItemKey = key; mFileName = string.Empty; mSize = size; mImage = image; mState = state; mUseEmbeddedThumbnails = useEmbeddedThumbnails; mIsVirtualItem = true; disposed = false; }