毫秒级的时间处理上G的图片(生成缩略图)
测试环境:
测试图片(30M):
测试计时方法:
- Stopwatch sw1 = new Stopwatch();
- sw1.Start();
- //TODO......
- sw1.Stop();
- string xx = sw1.ElapsedMilliseconds.ToString();
- MessageBox.Show(xx);
方法一,(1张30M图片,用时799毫秒)
- public Image getThumbNailUsingGetThumbnailImage(string fileName)
- {
- Image img = Image.FromFile(fileName);
- return img.GetThumbnailImage(, , null, IntPtr.Zero);
- }
方法二,(1张30M图片,用时1329毫秒)
- public Image createThumbnailUsingGDI(ref Image imgPhoto, int destWidth, int destHeight)
- {
- int sourceX = ;
- int sourceY = ;
- int destX = ;
- int destY = ;
- int sourceWidth = imgPhoto.Width;
- int sourceHeight = imgPhoto.Height;
- Bitmap b = new Bitmap(destWidth, destHeight);
- Graphics grPhoto = Graphics.FromImage(b);
- grPhoto.FillRectangle(Brushes.DarkGray, new Rectangle(destX, destY, destWidth, destHeight));
- grPhoto.DrawLine(new Pen(Brushes.LightGray), new Point(, destHeight - ), new Point(destWidth, destHeight - ));
- grPhoto.DrawLine(new Pen(Brushes.LightGray), new Point(destWidth - , ), new Point(destWidth - , destHeight));
- //shade right
- grPhoto.FillRectangle(Brushes.White, new Rectangle(destWidth - , , , ));
- grPhoto.FillRectangle(Brushes.White, new Rectangle(destWidth - , , , ));
- grPhoto.FillRectangle(Brushes.White, new Rectangle(destWidth - , , , ));
- //shade botton
- grPhoto.FillRectangle(Brushes.White, new Rectangle(, destHeight - , , ));
- grPhoto.FillRectangle(Brushes.White, new Rectangle(, destHeight - , , ));
- grPhoto.FillRectangle(Brushes.White, new Rectangle(, destHeight - , , ));
- grPhoto.DrawImage(imgPhoto, new Rectangle(destX + , destY + , destWidth - , destHeight - ), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);
- grPhoto.Dispose();
- return b;
- }
方法三,(1张30M图片,用时1636毫秒)
- public Image getThumbNailWithFrame(string fileName)
- {
- FileStream fs = new FileStream(fileName, FileMode.Open);
- Image im = Image.FromStream(fs);
- Size szMax = new Size(, );
- Size sz = getProportionalSize(szMax, im.Size);
- // superior image quality
- Bitmap bmpResized = new Bitmap(sz.Width, sz.Height);
- using (Graphics g = Graphics.FromImage(bmpResized))
- {
- g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.FillRectangle(Brushes.White, , , sz.Width, sz.Height);
- int FrameWidth = ;//decides the frame border width
- g.DrawRectangle(new Pen(Color.Silver, FrameWidth - ), , , sz.Width - , sz.Height - );
- FrameWidth += ;//decide the frame width
- g.DrawImage(im, new Rectangle(FrameWidth, FrameWidth, sz.Width - FrameWidth * , sz.Height - FrameWidth * ), new Rectangle(Point.Empty, im.Size), GraphicsUnit.Pixel);
- }
- im.Dispose(); im = null;
- fs.Close(); fs.Dispose(); fs = null;
- return bmpResized;
- }
- private Size getProportionalSize(Size szMax, Size szReal)
- {
- int nWidth;
- int nHeight;
- double sMaxRatio;
- double sRealRatio;
- if (szMax.Width < || szMax.Height < || szReal.Width < || szReal.Height < )
- return Size.Empty;
- sMaxRatio = (double)szMax.Width / (double)szMax.Height;
- sRealRatio = (double)szReal.Width / (double)szReal.Height;
- if (sMaxRatio < sRealRatio)
- {
- nWidth = Math.Min(szMax.Width, szReal.Width);
- nHeight = (int)Math.Round(nWidth / sRealRatio);
- }
- else
- {
- nHeight = Math.Min(szMax.Height, szReal.Height);
- nWidth = (int)Math.Round(nHeight * sRealRatio);
- }
- return new Size(nWidth, nHeight);
- }
方法四,(1张30M图片,用时1664毫秒)
- public Image getThumbNail(string fileName)
- {
- FileStream fs = new FileStream(fileName, FileMode.Open);
- Image im = Image.FromStream(fs);
- Size szMax = new Size(, );
- Size sz = getProportionalSize(szMax, im.Size);
- // superior image quality
- Bitmap bmpResized = new Bitmap(sz.Width, sz.Height);
- using (Graphics g = Graphics.FromImage(bmpResized))
- {
- g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.DrawImage(
- im,
- new Rectangle(Point.Empty, sz),
- new Rectangle(Point.Empty, im.Size),
- GraphicsUnit.Pixel);
- }
- im.Dispose(); im = null;
- fs.Close(); fs.Dispose(); fs = null;
- return bmpResized;
- }
- private Size getProportionalSize(Size szMax, Size szReal)
- {
- int nWidth;
- int nHeight;
- double sMaxRatio;
- double sRealRatio;
- if (szMax.Width < || szMax.Height < || szReal.Width < || szReal.Height < )
- return Size.Empty;
- sMaxRatio = (double)szMax.Width / (double)szMax.Height;
- sRealRatio = (double)szReal.Width / (double)szReal.Height;
- if (sMaxRatio < sRealRatio)
- {
- nWidth = Math.Min(szMax.Width, szReal.Width);
- nHeight = (int)Math.Round(nWidth / sRealRatio);
- }
- else
- {
- nHeight = Math.Min(szMax.Height, szReal.Height);
- nWidth = (int)Math.Round(nHeight * sRealRatio);
- }
- return new Size(nWidth, nHeight);
- }
方法五,(1张30M图片,用时735毫秒)
- public Image createThumbFromProperty(string file)
- {
- Image image = new Bitmap(file);
- Image Thumb = null;
- PropertyItem[] propItems = image.PropertyItems;
- foreach (PropertyItem propItem in propItems)
- {
- if (propItem.Id == 0x501B)
- {
- byte[] imageBytes = propItem.Value;
- MemoryStream stream = new MemoryStream(imageBytes.Length);
- stream.Write(imageBytes, , imageBytes.Length);
- Thumb = Image.FromStream(stream);
- break;
- }
- }
- return Thumb;
- }
方法六,(50张30M图片,237毫秒)
- using System;
- using System.Diagnostics;
- using System.Drawing;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Text;
- //网址:https://www.experts-exchange.com/questions/21789724/How-to-create-thumbnail.html
- namespace 缩略图查看
- {
- public class ShellThumbnail : IDisposable
- {
- [Flags]
- private enum ESTRRET
- {
- STRRET_WSTR = ,
- STRRET_OFFSET = ,
- STRRET_CSTR =
- }
- [Flags]
- private enum ESHCONTF
- {
- SHCONTF_FOLDERS = ,
- SHCONTF_NONFOLDERS = ,
- SHCONTF_INCLUDEHIDDEN = ,
- }
- [Flags]
- private enum ESHGDN
- {
- SHGDN_NORMAL = ,
- SHGDN_INFOLDER = ,
- SHGDN_FORADDRESSBAR = ,
- SHGDN_FORPARSING =
- }
- [Flags]
- private enum ESFGAO
- {
- SFGAO_CANCOPY = ,
- SFGAO_CANMOVE = ,
- SFGAO_CANLINK = ,
- SFGAO_CANRENAME = ,
- SFGAO_CANDELETE = ,
- SFGAO_HASPROPSHEET = ,
- SFGAO_DROPTARGET = ,
- SFGAO_CAPABILITYMASK = ,
- SFGAO_LINK = ,
- SFGAO_SHARE = ,
- SFGAO_READONLY = ,
- SFGAO_GHOSTED = ,
- SFGAO_DISPLAYATTRMASK = ,
- SFGAO_FILESYSANCESTOR = ,
- SFGAO_FOLDER = ,
- SFGAO_FILESYSTEM = ,
- SFGAO_HASSUBFOLDER = -,
- SFGAO_CONTENTSMASK = -,
- SFGAO_VALIDATE = ,
- SFGAO_REMOVABLE = ,
- SFGAO_COMPRESSED = ,
- }
- private enum EIEIFLAG
- {
- IEIFLAG_ASYNC = ,
- IEIFLAG_CACHE = ,
- IEIFLAG_ASPECT = ,
- IEIFLAG_OFFLINE = ,
- IEIFLAG_GLEAM = ,
- IEIFLAG_SCREEN = ,
- IEIFLAG_ORIGSIZE = ,
- IEIFLAG_NOSTAMP = ,
- IEIFLAG_NOBORDER = ,
- IEIFLAG_QUALITY =
- }
- [StructLayout(LayoutKind.Sequential, Pack = , Size = , CharSet = CharSet.Auto)]
- private struct STRRET_CSTR
- {
- public ESTRRET uType;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
- public byte[] cStr;
- }
- [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)]
- private struct STRRET_ANY
- {
- [FieldOffset()]
- public ESTRRET uType;
- [FieldOffset()]
- public IntPtr pOLEString;
- }
- [StructLayoutAttribute(LayoutKind.Sequential)]
- private struct SIZE
- {
- public int cx;
- public int cy;
- }
- [ComImport(), Guid("00000000-0000-0000-C000-000000000046")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IUnknown
- {
- [PreserveSig()]
- IntPtr QueryInterface(ref Guid riid, ref IntPtr pVoid);
- [PreserveSig()]
- IntPtr AddRef();
- [PreserveSig()]
- IntPtr Release();
- }
- [ComImportAttribute()]
- [GuidAttribute("00000002-0000-0000-C000-000000000046")]
- [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IMalloc
- {
- [PreserveSig()]
- IntPtr Alloc(int cb);
- [PreserveSig()]
- IntPtr Realloc(IntPtr pv, int cb);
- [PreserveSig()]
- void Free(IntPtr pv);
- [PreserveSig()]
- int GetSize(IntPtr pv);
- [PreserveSig()]
- int DidAlloc(IntPtr pv);
- [PreserveSig()]
- void HeapMinimize();
- }
- [ComImportAttribute()]
- [GuidAttribute("000214F2-0000-0000-C000-000000000046")]
- [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IEnumIDList
- {
- [PreserveSig()]
- int Next(int celt, ref IntPtr rgelt, ref int pceltFetched);
- void Skip(int celt);
- void Reset();
- void Clone(ref IEnumIDList ppenum);
- }
- [ComImportAttribute()]
- [GuidAttribute("000214E6-0000-0000-C000-000000000046")]
- [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IShellFolder
- {
- void ParseDisplayName(IntPtr hwndOwner, IntPtr pbcReserved,
- [MarshalAs(UnmanagedType.LPWStr)]string lpszDisplayName,
- ref int pchEaten, ref IntPtr ppidl, ref int pdwAttributes);
- void EnumObjects(IntPtr hwndOwner,
- [MarshalAs(UnmanagedType.U4)]ESHCONTF grfFlags,
- ref IEnumIDList ppenumIDList);
- void BindToObject(IntPtr pidl, IntPtr pbcReserved, ref Guid riid,
- ref IShellFolder ppvOut);
- void BindToStorage(IntPtr pidl, IntPtr pbcReserved, ref Guid riid, IntPtr ppvObj);
- [PreserveSig()]
- int CompareIDs(IntPtr lParam, IntPtr pidl1, IntPtr pidl2);
- void CreateViewObject(IntPtr hwndOwner, ref Guid riid,
- IntPtr ppvOut);
- void GetAttributesOf(int cidl, IntPtr apidl,
- [MarshalAs(UnmanagedType.U4)]ref ESFGAO rgfInOut);
- void GetUIObjectOf(IntPtr hwndOwner, int cidl, ref IntPtr apidl, ref Guid riid, ref int prgfInOut, ref IUnknown ppvOut);
- void GetDisplayNameOf(IntPtr pidl,
- [MarshalAs(UnmanagedType.U4)]ESHGDN uFlags,
- ref STRRET_CSTR lpName);
- void SetNameOf(IntPtr hwndOwner, IntPtr pidl,
- [MarshalAs(UnmanagedType.LPWStr)]string lpszName,
- [MarshalAs(UnmanagedType.U4)] ESHCONTF uFlags,
- ref IntPtr ppidlOut);
- }
- [ComImportAttribute(), GuidAttribute("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IExtractImage
- {
- void GetLocation([Out(), MarshalAs(UnmanagedType.LPWStr)]
- StringBuilder pszPathBuffer, int cch, ref int pdwPriority, ref SIZE prgSize, int dwRecClrDepth, ref int pdwFlags);
- void Extract(ref IntPtr phBmpThumbnail);
- }
- private class UnmanagedMethods
- {
- [DllImport("shell32", CharSet = CharSet.Auto)]
- internal extern static int SHGetMalloc(ref IMalloc ppMalloc);
- [DllImport("shell32", CharSet = CharSet.Auto)]
- internal extern static int SHGetDesktopFolder(ref IShellFolder ppshf);
- [DllImport("shell32", CharSet = CharSet.Auto)]
- internal extern static int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath);
- [DllImport("gdi32", CharSet = CharSet.Auto)]
- internal extern static int DeleteObject(IntPtr hObject);
- }
- ~ShellThumbnail()
- {
- Dispose();
- }
- private IMalloc alloc = null;
- private bool disposed = false;
- private Size _desiredSize = new Size(, );
- private Bitmap _thumbNail;
- public Bitmap ThumbNail
- {
- get
- {
- return _thumbNail;
- }
- }
- public Size DesiredSize
- {
- get { return _desiredSize; }
- set { _desiredSize = value; }
- }
- private IMalloc Allocator
- {
- get
- {
- if (!disposed)
- {
- if (alloc == null)
- {
- UnmanagedMethods.SHGetMalloc(ref alloc);
- }
- }
- else
- {
- Debug.Assert(false, "Object has been disposed.");
- }
- return alloc;
- }
- }
- public Bitmap GetThumbnail(string fileName)
- {
- if (string.IsNullOrEmpty(fileName))
- return null;
- if (!File.Exists(fileName) && !Directory.Exists(fileName))
- {
- throw new FileNotFoundException(string.Format("The file '{0}' does not exist", fileName), fileName);
- }
- if (_thumbNail != null)
- {
- _thumbNail.Dispose();
- _thumbNail = null;
- }
- IShellFolder folder = null;
- try
- {
- folder = getDesktopFolder;
- }
- catch (Exception ex)
- {
- throw ex;
- }
- if (folder != null)
- {
- IntPtr pidlMain = IntPtr.Zero;
- try
- {
- int cParsed = ;
- int pdwAttrib = ;
- string filePath = Path.GetDirectoryName(fileName);
- folder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, filePath, ref cParsed, ref pidlMain, ref pdwAttrib);
- }
- catch (Exception ex)
- {
- Marshal.ReleaseComObject(folder);
- throw ex;
- }
- if (pidlMain != IntPtr.Zero)
- {
- Guid iidShellFolder = new Guid("000214E6-0000-0000-C000-000000000046");
- IShellFolder item = null;
- try
- {
- folder.BindToObject(pidlMain, IntPtr.Zero, ref iidShellFolder, ref item);
- }
- catch (Exception ex)
- {
- Marshal.ReleaseComObject(folder);
- Allocator.Free(pidlMain);
- throw ex;
- }
- if (item != null)
- {
- IEnumIDList idEnum = null;
- try
- {
- item.EnumObjects(IntPtr.Zero, (ESHCONTF.SHCONTF_FOLDERS | ESHCONTF.SHCONTF_NONFOLDERS), ref idEnum);
- }
- catch (Exception ex)
- {
- Marshal.ReleaseComObject(folder);
- Allocator.Free(pidlMain);
- throw ex;
- }
- if (idEnum != null)
- {
- int hRes = ;
- IntPtr pidl = IntPtr.Zero;
- int fetched = ;
- bool complete = false;
- while (!complete)
- {
- hRes = idEnum.Next(, ref pidl, ref fetched);
- if (hRes != )
- {
- pidl = IntPtr.Zero;
- complete = true;
- }
- else
- {
- if (_getThumbNail(fileName, pidl, item))
- {
- complete = true;
- }
- }
- if (pidl != IntPtr.Zero)
- {
- Allocator.Free(pidl);
- }
- }
- Marshal.ReleaseComObject(idEnum);
- }
- Marshal.ReleaseComObject(item);
- }
- Allocator.Free(pidlMain);
- }
- Marshal.ReleaseComObject(folder);
- }
- return ThumbNail;
- }
- private bool _getThumbNail(string file, IntPtr pidl, IShellFolder item)
- {
- IntPtr hBmp = IntPtr.Zero;
- IExtractImage extractImage = null;
- try
- {
- string pidlPath = PathFromPidl(pidl);
- if (Path.GetFileName(pidlPath).ToUpper().Equals(Path.GetFileName(file).ToUpper()))
- {
- IUnknown iunk = null;
- int prgf = ;
- Guid iidExtractImage = new Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1");
- item.GetUIObjectOf(IntPtr.Zero, , ref pidl, ref iidExtractImage, ref prgf, ref iunk);
- extractImage = (IExtractImage)iunk;
- if (extractImage != null)
- {
- Console.WriteLine("Got an IExtractImage object!");
- SIZE sz = new SIZE();
- sz.cx = DesiredSize.Width;
- sz.cy = DesiredSize.Height;
- StringBuilder location = new StringBuilder(, );
- int priority = ;
- int requestedColourDepth = ;
- EIEIFLAG flags = EIEIFLAG.IEIFLAG_ASPECT | EIEIFLAG.IEIFLAG_SCREEN;
- int uFlags = (int)flags;
- try
- {
- extractImage.GetLocation(location, location.Capacity, ref priority, ref sz, requestedColourDepth, ref uFlags);
- extractImage.Extract(ref hBmp);
- }
- catch (System.Runtime.InteropServices.COMException ex)
- {
- }
- if (hBmp != IntPtr.Zero)
- {
- _thumbNail = Bitmap.FromHbitmap(hBmp);
- }
- Marshal.ReleaseComObject(extractImage);
- extractImage = null;
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- catch (Exception ex)
- {
- if (hBmp != IntPtr.Zero)
- {
- UnmanagedMethods.DeleteObject(hBmp);
- }
- if (extractImage != null)
- {
- Marshal.ReleaseComObject(extractImage);
- }
- throw ex;
- }
- }
- private string PathFromPidl(IntPtr pidl)
- {
- StringBuilder path = new StringBuilder(, );
- int result = UnmanagedMethods.SHGetPathFromIDList(pidl, path);
- if (result == )
- {
- return string.Empty;
- }
- else
- {
- return path.ToString();
- }
- }
- private IShellFolder getDesktopFolder
- {
- get
- {
- IShellFolder ppshf = null;
- int r = UnmanagedMethods.SHGetDesktopFolder(ref ppshf);
- return ppshf;
- }
- }
- public void Dispose()
- {
- if (!disposed)
- {
- if (alloc != null)
- {
- Marshal.ReleaseComObject(alloc);
- }
- alloc = null;
- if (_thumbNail != null)
- {
- _thumbNail.Dispose();
- }
- disposed = true;
- }
- }
- }
- }
方法七,(50张30M图片,96毫秒)
速度最快,只要兄弟们推荐的多,我下午公布源码。^_^
最快速度源码,请接收
- using System;
- using System.IO;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Runtime.InteropServices;
- using System.Drawing.Drawing2D;
- namespace 缩略图查看
- {
- /// <summary>
- /// Allows reading of embedded thumbnail image from the EXIF information in an image.
- /// </summary>
- //public abstract class ExifThumbReader
- public class ExifThumbReader
- {
- // GDI plus functions
- [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- internal static extern int GdipGetPropertyItem(IntPtr image, int propid, int size, IntPtr buffer);
- [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- internal static extern int GdipGetPropertyItemSize(IntPtr image, int propid, out int size);
- [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- internal static extern int GdipLoadImageFromFile(string filename, out IntPtr image);
- [DllImport("gdiplus.dll", EntryPoint = "GdipDisposeImage", CharSet = CharSet.Unicode, ExactSpelling = true)]
- private static extern int GdipDisposeImage(IntPtr image);
- // EXIT tag value for thumbnail data. Value specified by EXIF standard
- private static int THUMBNAIL_DATA = 0x501B;
- /// <summary>
- /// Reads the thumbnail in the given image. If no thumbnail is found, returns null
- /// </summary>
- //public static Image ReadThumb(string imagePath)
- public Image ReadThumb(string imagePath)
- {
- const int GDI_ERR_PROP_NOT_FOUND = ; // Property not found error
- const int GDI_ERR_OUT_OF_MEMORY = ;
- IntPtr hImage = IntPtr.Zero;
- IntPtr buffer = IntPtr.Zero; // Holds the thumbnail data
- int ret;
- ret = GdipLoadImageFromFile(imagePath, out hImage);
- try
- {
- if (ret != )
- throw createException(ret);
- int propSize;
- ret = GdipGetPropertyItemSize(hImage, THUMBNAIL_DATA, out propSize);
- // Image has no thumbnail data in it. Return null
- if (ret == GDI_ERR_PROP_NOT_FOUND)
- return null;
- if (ret != )
- throw createException(ret);
- // Allocate a buffer in memory
- buffer = Marshal.AllocHGlobal(propSize);
- if (buffer == IntPtr.Zero)
- throw createException(GDI_ERR_OUT_OF_MEMORY);
- ret = GdipGetPropertyItem(hImage, THUMBNAIL_DATA, propSize, buffer);
- if (ret != )
- throw createException(ret);
- // buffer has the thumbnail data. Now we have to convert it to
- // an Image
- return convertFromMemory(buffer);
- }
- finally
- {
- // Free the buffer
- if (buffer != IntPtr.Zero)
- Marshal.FreeHGlobal(buffer);
- GdipDisposeImage(hImage);
- }
- }
- /// <summary>
- /// Generates an exception depending on the GDI+ error codes (I removed some error
- /// codes)
- /// </summary>
- private static Exception createException(int gdipErrorCode)
- {
- switch (gdipErrorCode)
- {
- case :
- return new ExternalException("Gdiplus Generic Error", -);
- case :
- return new ArgumentException("Gdiplus Invalid Parameter");
- case :
- return new OutOfMemoryException("Gdiplus Out Of Memory");
- case :
- return new InvalidOperationException("Gdiplus Object Busy");
- case :
- return new OutOfMemoryException("Gdiplus Insufficient Buffer");
- case :
- return new ExternalException("Gdiplus Generic Error", -);
- case :
- return new InvalidOperationException("Gdiplus Wrong State");
- case :
- return new ExternalException("Gdiplus Aborted", -);
- case :
- return new FileNotFoundException("Gdiplus File Not Found");
- case :
- return new OverflowException("Gdiplus Over flow");
- case :
- return new ExternalException("Gdiplus Access Denied", -);
- case :
- return new ArgumentException("Gdiplus Unknown Image Format");
- case :
- return new ExternalException("Gdiplus Not Initialized", -);
- case :
- return new ArgumentException("Gdiplus Property Not Supported Error");
- }
- return new ExternalException("Gdiplus Unknown Error", -);
- }
- /// <summary>
- /// Converts the IntPtr buffer to a property item and then converts its
- /// value to a Drawing.Image item
- /// </summary>
- private static Image convertFromMemory(IntPtr thumbData)
- {
- propertyItemInternal prop =
- (propertyItemInternal)Marshal.PtrToStructure
- (thumbData, typeof(propertyItemInternal));
- // The image data is in the form of a byte array. Write all
- // the bytes to a stream and create a new image from that stream
- byte[] imageBytes = prop.Value;
- MemoryStream stream = new MemoryStream(imageBytes.Length);
- stream.Write(imageBytes, , imageBytes.Length);
- return Image.FromStream(stream);
- }
- /// <summary>
- /// Used in Marshal.PtrToStructure().
- /// We need this dummy class because Imaging.PropertyItem is not a "blittable"
- /// class and Marshal.PtrToStructure only accepted blittable classes.
- /// (It's not blitable because it uses a byte[] array and that's not a blittable
- /// type. See MSDN for a definition of Blittable.)
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- private class propertyItemInternal
- {
- public int id = ;
- public int len = ;
- public short type = ;
- public IntPtr value = IntPtr.Zero;
- public byte[] Value
- {
- get
- {
- byte[] bytes = new byte[(uint)len];
- Marshal.Copy(value, bytes, , len);
- return bytes;
- }
- }
- }
- }
- }
测试结果:
方法 | 图片张数(张) | 每张大小(M) | 图片总大小 | 用时 |
方法一 | 50 | 30 | 1500M | 39950毫秒=40秒 |
方法二 | 50 | 30 | 1500M | 66450毫秒=66秒 |
方法三 | 50 | 30 | 1500M | 81800毫秒=81秒 |
方法四 | 50 | 30 | 1500M | 83200毫秒=83秒 |
方法五 | 50 | 30 | 1500M | 36750毫秒=37秒 |
方法六 | 50 | 30 | 1500M | 237毫秒 |
方法七 | 50 | 30 | 1500M | 96毫秒 |
毫秒级的时间处理上G的图片(生成缩略图)的更多相关文章
- 【.NET】上传文件,生成缩略图
类名:Upload using System; using System.Collections; using System.ComponentModel; using System.Data; us ...
- MACOS,LINUX,IOS上可用的毫秒级精度时间获取
二话不说,先上代码 void outputCurrentTime(uint32_t seq,const char* type){ struct timeval t_curr; gettimeofday ...
- spring boot:实现图片文件上传并生成缩略图(spring boot 2.3.1)
一,为什么要给图片生成缩略图? 1, 用户上传的原始图片如果太大,不能直接展示在网站页面上, 因为不但流费server的流量,而且用户打开时非常费时间, 所以要生成缩略图. 2,服务端管理图片要注意的 ...
- VC中如何获取当前时间(精度达到毫秒级)
标 题: VC中如何获取当前时间(精度达到毫秒级)作 者: 0xFFFFCCCC时 间: 2013-06-24链 接: http://www.cnblogs.com/Y4ng/p/Millisecon ...
- Linux下得到毫秒级时间--C语言实现(转-度娘818)
Linux下得到毫秒级时间--C语言实现 原文链接: http://www.cnblogs.com/nwf5d/archive/2011/06/03/2071247.html #ifdef HAVE_ ...
- GetSystemTime API可以得到毫秒级时间
用Now返回的日期格式中年只有2位,即2000年显示为00, 这似乎不太令人满意. 此外Now和Time都只能获得精确到秒的时间,为了得到更精确的毫秒级时间,可以使用API函数GetSystemTim ...
- OKEx交易所交易记录日期时间转毫秒级时间戳
本文介绍如何将OKEx交易所成交记录数据中的日期时间转毫秒级时间戳. 作者:比特量化 1. OKEx交易记录格式 [ { "time":"2019-09-14T10:29 ...
- 使用bitset实现毫秒级查询
前言 因为业务要求api的一次请求响应时间在10ms以内,所以传统的数据库查询操作直接被排除(网络io和磁盘io).通过调研,最终使用了bieset,目前已经正常运行了很久 *** bitset介绍 ...
- 移动端web开发安卓和ios客户端在时间转换上的差异性问题
作为一名移动前端开发的人员,平时遇到的兼容性问题不在少数.那么,今天就来说一下最近遇到的一个小坑(关于Android和ios在时间转换上的差异性问题)话不多说,直接上重点. 最近接到了一个需求,很简单 ...
随机推荐
- 控制台查看原生sql
情况:当tomcat运行时,项目运行过程中,控制台没有打印出原生sql语句: 解决办法如下: 在 META-INF 文件夹下,查找 persistence.xml 这个文件(这里注意可能一个项目不止 ...
- SQL Server 得到数据库中所有表的名称及数据条数
--方法一if exists ( select * from dbo.sysobjects where id = object_id(N'[dbo].[TableSpace]') and object ...
- java io流 图片和字符串之间的转换
package com.yundongsports.arena.controller.basketballsite;import com.yundongsports.arena.ResponseVo. ...
- Android 延时执行任务的三种简单方法
开启一个新的线程 new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (Interrupted ...
- 苹果mac电脑中brew的安装使用及卸载详细教程
brew 又叫Homebrew,是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或者卸载软件, 只需要一个命令, 非常方便 brew类似ubuntu系统下的apt-get的功能 安装br ...
- update maven之后jre被改成1.5的问题
在 pom.xml 中添加如下代码: <build> <plugins> <plugin> <groupId>org.apache.maven.plug ...
- 添加ssh key
我现在根据<github入门和实践>来去摸索github 其实,我发现自己在看github时,感觉不适应,是因为自己太久没有碰到英文了.可以联想到以前当看到一个网页,根据汉字的标题或描述, ...
- 测试...外部指针访问private
#include<iostream> using namespace std; class A{ public: int* getPointer(){ return &m; } v ...
- mssql与mysql 数据迁移
概要: mssql向mysql迁移的实例,所要用到的工具bcp和load data local infile. 由于订单记录的数据是存放在mssql服务器上的,而项目需求把数据迁移到mysql ser ...
- Jaunt登陆索尼PSVR,为其提供大量VR视频
索尼PS VR自从推出就广受用户青睐,当然不仅仅是其低于高端VR头显的价格,还在于PS VR提供的丰富游戏内容.近日,国外视频网站Jaunt还专门为PSVR推出了专版APP,为其提供超过 150 个沉 ...