2011-05-04 149 views
16

在.NET中生成缩略图的最快和最可靠的方法是什么?我需要得到任何图像,以JPEG格式压缩并调整大小。在ASP.NET中生成图像缩略图?

我见过几个GDI +的例子,一些非自由组件,我记得WPF有一些关于图像的好东西。 GDI +很老,WPF的东西可能对服务器环境没有任何好处。

这必须在完全信任的运行的ASP.NET MVC应用程序中运行,并且如果可能的话同步运行。

你会推荐什么?

UPDATE:

基于Mantorok's answer我已经制定了这个例子,但它仍然是GDI +,它崩溃,如果我试图用一个大的图像:

public void GenerateThumbnail(String filename, Int32? desiredWidth, 
    Int32? desiredHeight, Int64 quality, Stream s) 
{ 
    using (Image image = Image.FromFile(filename)) 
    { 
     Int32 width=0, height=0; 

     if ((!desiredHeight.HasValue && !desiredWidth.HasValue) || 
      (desiredHeight.HasValue && desiredWidth.HasValue)) 
      throw new ArgumentException(
       "You have to specify a desired width OR a desired height"); 

     if (desiredHeight.HasValue) 
     { 
      width = (desiredHeight.Value * image.Width)/image.Height; 
      height = desiredHeight.Value; 
     } 
     else 
     { 
      height = (desiredWidth.Value * image.Height)/image.Width; 
      width = desiredWidth.Value; 
     } 

     using (var newImage = new Bitmap(width, height)) 
     using (var graphics = Graphics.FromImage(newImage)) 
     using (EncoderParameter qualityParam = 
      new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 
       quality)) 
     using (EncoderParameters encoderParams = new EncoderParameters(1)) 
     { 
      graphics.DrawImage(image, 0, 0, width, height); 
      ImageCodecInfo jpegCodec = ImageCodecInfo.GetImageEncoders(). 
       Single(e => e.MimeType.Equals("image/jpeg", 
        StringComparison.Ordinal)); 
      encoderParams.Param[0] = qualityParam; 
      newImage.Save(s, jpegCodec, encoderParams); 
     } 
    } 
} 
+0

什么是异常被抛出? – Mantorok 2011-05-05 11:38:26

+0

Image.FromFile中的OutOfMemoryException(文件名) – vtortola 2011-05-06 17:01:57

+0

Blimey!文件有多大!? – Mantorok 2011-05-09 10:20:02

回答

5

对于密集的服务器端代码,我建议您使用除GDI +以外的其他技术,这些技术还没有设计用于处理图像(以流式方式)。

您可以使用Windows Imaging Component或WPF执行此任务。这里是如何做到这一点的快速和一个很好的例子 - 更重要的 - 可扩展的方式在这里:

The fastest way to resize images from ASP.NET. And it’s (more) supported-ish.

+0

太好了,谢谢! – vtortola 2011-05-11 08:19:31

+0

http://imageresizing.net库现在提供基于WIC的调整大小。它比Bertrand的示例代码更快,并且可以正确管理内存。它非常简单易用。 – 2012-01-09 21:01:07

2

我不能说无论这是最有效的方式,但这里是我写的代码片段,用于从大图像中产生3个较小的图像:

private void GenerateImages(byte[] data, string extension, string filename) 
    { 
    // Assuming data is the original filename. 
    var ms = new MemoryStream(data); 
    var image = Image.FromStream(ms); 
    image.Save(filename); 
    ResizeImage(image, 800, 600, "large.jpg"); 
    ResizeImage(image, 480, 320, "medium.jpg"); 
    ResizeImage(image, 192, 144, "small.jpg"); 
    } 

    private void ResizeImage(Image image, int width, int height, string filename) 
    { 
    using (var newImage = new Bitmap(width, height)) 
    { 
     var graphics = Graphics.FromImage(newImage); 
     graphics.DrawImage(image, 0, 0, width, height); 
     newImage.Save(filename, ImageFormat.Jpeg); 
    } 
    } 
3

我使用ImageMagick的进行照片处理

修订

型号:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.IO; 
using ImageMagickObject; 

namespace photostorage.Models 
{ 
    public class PhotoProcessing 
    { 
     public MagickImage ResizeImg(string filepath, string filename) 
     { 
      Object[] rotate = new Object[] { filepath + "/" + filename, 
       "-auto-orient", filepath + "/" + filename }; 
      Object[] big = new Object[] { filepath + "/" + filename, 
       "-resize", "800", filepath + "/" + "big_" + filename }; 
      Object[] middle = new Object[] { filepath + "/big_" + filename, 
       "-resize", "400", filepath + "/" + "mid_" + filename }; 
      Object[] small = new Object[] { filepath + "/mid_" + filename, 
       "-resize", "200", filepath + "/" + "small_" + filename }; 
      Object[] crop = new Object[] { filepath + "/small_" + filename, 
       "-resize", "50", filepath + "/" + "crop_" + filename }; 
      ImageMagickObject.MagickImage img = 
       new ImageMagickObject.MagickImage(); 
      img.Convert(rotate); 
      img.Convert(big); 
      img.Convert(middle); 
      img.Convert(small); 
      img.Convert(crop); 
      return img; 
     } 
    } 
} 

控制器:

PhotoProcessing resizeImg = new PhotoProcessing(); 
[HttpPost] 
public string Index(params,params,params...) 
{ 
    var GetResize = resizeImg.ResizeImg(
     destinationFolder + "/" + curFolder, fullFileName); 
} 
+0

你如何使用它?我找到了一个.net包装器,但它没有记录,并且你提到的类不存在。 – vtortola 2011-05-04 14:30:37

+0

我不使用ImageMagick.NET - 我使用ImageMagickObject dll(原因,就像你写的,.net vertion完全没有记录)。等一下,我会在这里提供完整的解决方案 – 2011-05-04 14:32:37

+0

检查更新 – 2011-05-04 14:38:25

0

我使用Aurigma图片上传工具。这是非常好的控制。但支付你可以检查aurigma

3

看到这里Create thumbnail image

我的回答有关于图像的功能,它返回一个像这样的缩略图:

Image image = Image.FromFile(fileName); 
Image thumb = image.GetThumbnailImage(120, 120,()=>false, IntPtr.Zero); 
thumb.Save(Path.ChangeExtension(fileName, "thumb")); 
6

这已经为我做了罚款岁:

public static void CreateThumbnail(string filename, int desiredWidth, int desiredHeight, string outFilename) 
{ 
    using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename)) 
    { 
     float widthRatio = (float)img.Width/(float)desiredWidth; 
     float heightRatio = (float)img.Height/(float)desiredHeight; 
     // Resize to the greatest ratio 
     float ratio = heightRatio > widthRatio ? heightRatio : widthRatio; 
     int newWidth = Convert.ToInt32(Math.Floor((float)img.Width/ratio)); 
     int newHeight = Convert.ToInt32(Math.Floor((float)img.Height/ratio)); 
     using (System.Drawing.Image thumb = img.GetThumbnailImage(newWidth, newHeight, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailImageAbortCallback), IntPtr.Zero)) 
     { 
      thumb.Save(outFilename, System.Drawing.Imaging.ImageFormat.Jpeg); 
     } 
    } 
} 

public static bool ThumbnailImageAbortCallback() 
{ 
    return true; 
} 
+0

古朴典雅;我偷这个肯定:) – kite 2013-05-01 13:36:50

+0

尽管如此,与大图像。例如1920 * 60000。不够健壮。 – TEK 2016-02-20 12:11:07