Подтвердить что ты не робот

Создание эскизов изображений в ASP.NET?

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

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

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

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

UPDATE:

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

Ответ 1

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

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

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

Ответ 2

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

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;
}

Ответ 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);
}

Ответ 4

Смотрите мой ответ здесь Создайте эскиз

На изображении есть функция, которая возвращает миниатюру следующим образом:

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

Ответ 5

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

Ответ 7

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