Створіть ескіз


96

Я хочу відобразити ескіз зображення у сітці з місця розташування файлу. Як згенерувати .jpegфайл? Я використовую C#мову з asp.net.


6
ImageResizer - це безпечна для сервера бібліотека, створена для того, щоб робити саме те, що вам потрібно. На відміну від GetThumbnailImage, він дає високоякісні результати, і на відміну від зразків коду, він не витікає з пам'яті, як сито. Можливо, вам зараз все одно, але через кілька місяців це станеться, коли ви опинитесь у колінах у стрижнях.
Річка Ліліт



ImageResizer чудовий, але це не безкоштовно
Бобан Стояновський

Відповіді:


222

Ви повинні використовувати GetThumbnailImageметод у Imageкласі:

https://msdn.microsoft.com/en-us/library/8t23aykb%28v=vs.110%29.aspx

Ось приблизний приклад, який бере файл зображення та робить із нього ескіз, а потім зберігає його назад на диск.

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

Він знаходиться у просторі імен System.Drawing (у System.Drawing.dll).

Поведінка:

Якщо зображення містить вбудоване ескіз, цей метод отримує вбудований ескіз і масштабує його до потрібного розміру. Якщо зображення не містить вбудованого мініатюрного зображення, цей метод створює мініатюрне зображення шляхом масштабування основного зображення.


Важливо: розділ зауважень у наведеному вище посиланні Microsoft попереджає про певні потенційні проблеми:

GetThumbnailImageМетод добре працює , коли запитуваний мініатюрне зображення має розмір близько 120 х 120 пікселів. Якщо ви запитуєте велике ескізне зображення (наприклад, 300 x 300) із зображення, яке має вбудований ескіз, це може спричинити помітну втрату якості ескізного зображення .

Можливо, було б краще масштабувати основне зображення (замість масштабування вбудованого ескізу), викликаючи DrawImageметод.


5
Його можна використовувати лише для зображень у форматі JPG, як правило. Якщо ви спробуєте змінити розмір PNG-зображення таким чином, ви отримаєте цю помилку.
HBlackorby

Дійсно, використовував це, щоб отримати мініатюру 400x225 фотографії у повному форматі HD, а розмір отриманої "мініатюри" становив 200 кБ (оригінал 350 кБ). Цього методу слід уникати.
Vojtěch Dohnal

1
@NathanaelJones, ти серйозно? ImageResizer не безкоштовний для бізнесу.
Кіаран Галлахер,

26

Наступний код буде писати зображення пропорційно відповіді, ви можете змінити код для своєї мети:

public void WriteImage(string path, int width, int height)
{
    Bitmap srcBmp = new Bitmap(path);
    float ratio = srcBmp.Width / srcBmp.Height;
    SizeF newSize = new SizeF(width, height * ratio);
    Bitmap target = new Bitmap((int) newSize.Width,(int) newSize.Height);
    HttpContext.Response.Clear();
    HttpContext.Response.ContentType = "image/jpeg";
    using (Graphics graphics = Graphics.FromImage(target))
    {
        graphics.CompositingQuality = CompositingQuality.HighSpeed;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height);
        using (MemoryStream memoryStream = new MemoryStream()) 
        {
            target.Save(memoryStream, ImageFormat.Jpeg);
            memoryStream.WriteTo(HttpContext.Response.OutputStream);
        }
    }
    Response.End();
}

Я вказав мій локальний шлях до файлу в рядковому шляху. він повертає "заданий формат шляху не підтримується".
Гопал Палрадж

я дав так ... var path = @ "C: \ Users \ Gopal \ Desktop \ files.jpeg"; Bitmap srcBmp = новий Bitmap (шлях);
Гопал Палрадж

Для тих, хто використовує HttpResponseMessage:response.Content = new ByteArrayContent(memoryStream.ToArray());
Hp93

обережно, цей код передбачає, що зображення "горизонтальні" (
Олексій,

8

Ось повний приклад того, як створити менший малюнок (ескіз). Цей фрагмент змінює розмір зображення, повертає його за потреби (якщо телефон тримався вертикально) і розміщує зображення, якщо ви хочете створити квадратні великі пальці. Цей фрагмент створює JPEG, але його можна легко змінити для інших типів файлів. Навіть якщо зображення буде менше максимально дозволеного розміру, зображення все одно буде стиснене, а його роздільна здатність змінена, щоб створити зображення з однаковим рівнем dpi та рівнем стиснення.

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

//set the resolution, 72 is usually good enough for displaying images on monitors
float imageResolution = 72;

//set the compression level. higher compression = better quality = bigger images
long compressionLevel = 80L;


public Image resizeImage(Image image, int maxWidth, int maxHeight, bool padImage)
{
    int newWidth;
    int newHeight;

    //first we check if the image needs rotating (eg phone held vertical when taking a picture for example)
    foreach (var prop in image.PropertyItems)
    {
        if (prop.Id == 0x0112)
        {
            int orientationValue = image.GetPropertyItem(prop.Id).Value[0];
            RotateFlipType rotateFlipType = getRotateFlipType(orientationValue);
            image.RotateFlip(rotateFlipType);
            break;
        }
    }

    //apply the padding to make a square image
    if (padImage == true)
    {
        image = applyPaddingToImage(image, Color.Red);
    }

    //check if the with or height of the image exceeds the maximum specified, if so calculate the new dimensions
    if (image.Width > maxWidth || image.Height > maxHeight)
    {
        double ratioX = (double)maxWidth / image.Width;
        double ratioY = (double)maxHeight / image.Height;
        double ratio = Math.Min(ratioX, ratioY);

        newWidth = (int)(image.Width * ratio);
        newHeight = (int)(image.Height * ratio);
    }
    else
    {
        newWidth = image.Width;
        newHeight = image.Height;
    }

    //start the resize with a new image
    Bitmap newImage = new Bitmap(newWidth, newHeight);

    //set the new resolution
    newImage.SetResolution(imageResolution, imageResolution);

    //start the resizing
    using (var graphics = Graphics.FromImage(newImage))
    {
        //set some encoding specs
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        graphics.DrawImage(image, 0, 0, newWidth, newHeight);
    }

    //save the image to a memorystream to apply the compression level
    using (MemoryStream ms = new MemoryStream())
    {
        EncoderParameters encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, compressionLevel);

        newImage.Save(ms, getEncoderInfo("image/jpeg"), encoderParameters);

        //save the image as byte array here if you want the return type to be a Byte Array instead of Image
        //byte[] imageAsByteArray = ms.ToArray();
    }

    //return the image
    return newImage;
}


//=== image padding
public Image applyPaddingToImage(Image image, Color backColor)
{
    //get the maximum size of the image dimensions
    int maxSize = Math.Max(image.Height, image.Width);
    Size squareSize = new Size(maxSize, maxSize);

    //create a new square image
    Bitmap squareImage = new Bitmap(squareSize.Width, squareSize.Height);

    using (Graphics graphics = Graphics.FromImage(squareImage))
    {
        //fill the new square with a color
        graphics.FillRectangle(new SolidBrush(backColor), 0, 0, squareSize.Width, squareSize.Height);

        //put the original image on top of the new square
        graphics.DrawImage(image, (squareSize.Width / 2) - (image.Width / 2), (squareSize.Height / 2) - (image.Height / 2), image.Width, image.Height);
    }

    //return the image
    return squareImage;
}


//=== get encoder info
private ImageCodecInfo getEncoderInfo(string mimeType)
{
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();

    for (int j = 0; j < encoders.Length; ++j)
    {
        if (encoders[j].MimeType.ToLower() == mimeType.ToLower())
        {
            return encoders[j];
        }
    }

    return null;
}


//=== determine image rotation
private RotateFlipType getRotateFlipType(int rotateValue)
{
    RotateFlipType flipType = RotateFlipType.RotateNoneFlipNone;

    switch (rotateValue)
    {
        case 1:
            flipType = RotateFlipType.RotateNoneFlipNone;
            break;
        case 2:
            flipType = RotateFlipType.RotateNoneFlipX;
            break;
        case 3:
            flipType = RotateFlipType.Rotate180FlipNone;
            break;
        case 4:
            flipType = RotateFlipType.Rotate180FlipX;
            break;
        case 5:
            flipType = RotateFlipType.Rotate90FlipX;
            break;
        case 6:
            flipType = RotateFlipType.Rotate90FlipNone;
            break;
        case 7:
            flipType = RotateFlipType.Rotate270FlipX;
            break;
        case 8:
            flipType = RotateFlipType.Rotate270FlipNone;
            break;
        default:
            flipType = RotateFlipType.RotateNoneFlipNone;
            break;
    }

    return flipType;
}


//== convert image to base64
public string convertImageToBase64(Image image)
{
    using (MemoryStream ms = new MemoryStream())
    {
        //convert the image to byte array
        image.Save(ms, ImageFormat.Jpeg);
        byte[] bin = ms.ToArray();

        //convert byte array to base64 string
        return Convert.ToBase64String(bin);
    }
}

Для користувачів asp.net невеликий приклад того, як завантажити файл, змінити його розмір і відобразити результат на сторінці.

//== the button click method
protected void Button1_Click(object sender, EventArgs e)
{
    //check if there is an actual file being uploaded
    if (FileUpload1.HasFile == false)
    {
        return;
    }

    using (Bitmap bitmap = new Bitmap(FileUpload1.PostedFile.InputStream))
    {
        try
        {
            //start the resize
            Image image = resizeImage(bitmap, 256, 256, true);

            //to visualize the result, display as base64 image
            Label1.Text = "<img src=\"data:image/jpg;base64," + convertImageToBase64(image) + "\">";

            //save your image to file sytem, database etc here
        }
        catch (Exception ex)
        {
            Label1.Text = "Oops! There was an error when resizing the Image.<br>Error: " + ex.Message;
        }
    }
}

Мені сподобався цей приклад коду і я вибрав його використовувати. Однак незалежно від того, які зміни я вніс у різні параметри (imageResolution, compressionLevel, CompositingMode, CompositingQuality, SmoothingMode, InterpolationMode, PixelOffsetMode) розмір файлу зображення лише зменшив незначну кількість. І я ніколи не бачив різниці у створеному образі. Нарешті, я вирішив зберегти зображення у файл, а не в потік пам'яті, і зміг побачити різкі зміни. Для кожного, хто використовує це, здається, збереження в потоці пам'яті не впливає на повернене зображення.
BLaminack

1

Ось приклад перетворення зображення з високою роздільною здатністю у розмір ескізів

protected void Button1_Click(object sender, EventArgs e)
{
    //----------        Getting the Image File
    System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("~/profile/Avatar.jpg"));

    //----------        Getting Size of Original Image
    double imgHeight = img.Size.Height;
    double imgWidth = img.Size.Width;

    //----------        Getting Decreased Size
    double x = imgWidth / 200;
    int newWidth = Convert.ToInt32(imgWidth / x);
    int newHeight = Convert.ToInt32(imgHeight / x);

    //----------        Creating Small Image
    System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
    System.Drawing.Image myThumbnail = img.GetThumbnailImage(newWidth, newHeight, myCallback, IntPtr.Zero);

    //----------        Saving Image
    myThumbnail.Save(Server.MapPath("~/profile/NewImage.jpg"));
}
public bool ThumbnailCallback()
{
    return false;
}

Джерело- http://iknowledgeboy.blogspot.in/2014/03/c-creating-thumbnail-of-large-image-by.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.