Создание эскизов изображений в ASP.NET? - PullRequest
16 голосов
/ 04 мая 2011

Какой самый быстрый и надежный способ создания миниатюр в .NET?Мне нужно получить любое изображение, сжать его в формате JPEG и изменить его размер.

Я видел несколько примеров с GDI +, некоторыми несвободными компонентами, и я помню, что в WPF есть кое-что хорошее о работе с изображениями.GDI + довольно старый, и материал WPF, возможно, не имеет никаких преимуществ в серверной среде.

Это должно работать в приложении ASP.NET MVC, которое работает с полным доверием и, если возможно, синхронно.

Что бы вы порекомендовали?

ОБНОВЛЕНИЕ:

Основано на Ответ Манторка Я разработал этот пример, но он все еще 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);
        }
    }
}

Ответы [ 7 ]

6 голосов
/ 04 мая 2011

Это хорошо для меня годами:

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;
}
5 голосов
/ 04 мая 2011

Для интенсивного кода на стороне сервера я предлагаю вам использовать другие методы, кроме GDI +, которые не были предназначены для обработки фрагментов изображений по частям (потоковым способом).

Для этой задачи вы можете использовать Windows Imaging Component или WPF. Вот очень хороший пример того, как сделать это быстрым и, что более важно, масштабируемым образом:

Самый быстрый способ изменить размер изображения из ASP.NET. И это (более) поддерживается ish.

3 голосов
/ 04 мая 2011

См. Мой ответ здесь Создание миниатюры

Существует функция на изображении, которая возвращает миниатюру, подобную этой:

Image image = Image.FromFile(fileName);
Image thumb = image.GetThumbnailImage(120, 120, ()=>false, IntPtr.Zero);
thumb.Save(Path.ChangeExtension(fileName, "thumb"));
3 голосов
/ 04 мая 2011

Я использую 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);
}
2 голосов
/ 04 мая 2011

Я не могу сказать, является ли это наиболее эффективным способом, но вот фрагмент кода, который я написал для создания 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);
     }
  }
0 голосов
/ 04 мая 2011

Я использую Aurigma Image Uploader. это довольно хороший контроль. но это платно, вы можете проверить aurigma

0 голосов
/ 04 мая 2011

http://www.codeproject.com/KB/graphics/image_croppingVBNet.aspx

это изображение для обрезки по центру, надеюсь, я помогу вам больше ..

http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

...