예제 #1
0
 /// <summary>
 /// Open image and read metadata (.NET 2.0).
 /// </summary>
 /// <param name="path">Filepath of image</param>
 private void InitViaBmp(string path)
 {
     using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
     {
         if (Utility.IsImage(stream))
         {
             using (Image img = Image.FromStream(stream, false, false))
             {
                 if (img != null)
                 {
                     InitViaBmp(img);
                 }
             }
         }
     }
 }
        /// <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);
        }