Tạo hình ảnh thu nhỏ


96

Tôi muốn hiển thị hình ảnh thu nhỏ trong chế độ xem lưới từ vị trí tệp. Làm thế nào để tạo ra .jpegtệp đó? Tôi đang sử dụng C#ngôn ngữ với asp.net.


6
ImageResizer là một thư viện an toàn cho máy chủ được thiết kế để thực hiện chính xác những gì bạn cần. Không giống như GetThumbnailImage, nó tạo ra kết quả chất lượng cao và không giống như các mẫu mã, nó không làm rò rỉ bộ nhớ như một cái sàng. Bạn có thể không quan tâm bây giờ, nhưng bạn sẽ làm được sau vài tháng nữa khi đầu gối của bạn ngập sâu trong các bãi rác.
Sông Lilith



ImageResizer rất tuyệt, nhưng nó không miễn phí
Boban Stojanovski

Câu trả lời:


222

Bạn phải sử dụng GetThumbnailImagephương thức trong Imagelớp:

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

Đây là một ví dụ sơ lược về việc lấy một tệp hình ảnh và tạo một hình ảnh thu nhỏ từ tệp đó, sau đó lưu lại vào đĩa.

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

Nó nằm trong không gian tên System.Drawing (trong System.Drawing.dll).

Hành vi:

Nếu Hình ảnh chứa hình ảnh thu nhỏ được nhúng, phương pháp này sẽ truy xuất hình thu nhỏ được nhúng và chia tỷ lệ theo kích thước được yêu cầu. Nếu Hình ảnh không chứa hình ảnh thu nhỏ được nhúng, phương pháp này sẽ tạo hình ảnh thu nhỏ bằng cách chia tỷ lệ hình ảnh chính.


Quan trọng: phần nhận xét của liên kết Microsoft ở trên cảnh báo về một số vấn đề tiềm ẩn nhất định:

Các GetThumbnailImagephương pháp hoạt động tốt khi được yêu cầu thu nhỏ hình ảnh có kích thước khoảng 120 x 120 pixel. Nếu bạn yêu cầu hình ảnh thu nhỏ lớn (ví dụ: 300 x 300) từ Hình ảnh có hình thu nhỏ được nhúng, thì hình ảnh thu nhỏ đó có thể bị giảm chất lượng đáng kể .

Có thể tốt hơn là chia tỷ lệ hình ảnh chính (thay vì mở rộng hình thu nhỏ được nhúng) bằng cách gọi DrawImagephương thức.


5
Nó chỉ có thể được sử dụng trên ảnh JPG nói chung. Nếu bạn cố gắng thay đổi kích thước hình ảnh PNG như thế này, bạn sẽ gặp lỗi này.
HBlackorby

Thực sự, đã sử dụng tính năng này để lấy hình thu nhỏ 400x225 của một bức ảnh full hd và kích thước của "hình thu nhỏ" thu được là 200 kB (Gốc 350 kB). Phương pháp này là điều cần tránh.
Vojtěch Dohnal.

1
@NathanaelJones, bạn có nghiêm túc không? ImageResizer không miễn phí cho doanh nghiệp.
Ciaran Gallagher

26

Đoạn mã sau sẽ viết một hình ảnh tương ứng với phản hồi, bạn có thể sửa đổi mã cho mục đích của mình:

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

Tôi đã cho đường dẫn tệp cục bộ của mình trong đường dẫn chuỗi. nó trả về "định dạng đường dẫn nhất định không được hỗ trợ".
Gopal Palraj

tôi đã đưa ra như thế này ... var path = @ "C: \ Users \ Gopal \ Desktop \ files.jpeg"; Bitmap srcBmp = new Bitmap (đường dẫn);
Gopal Palraj

Đối với những người sử dụng HttpResponseMessage:response.Content = new ByteArrayContent(memoryStream.ToArray());
Hp93

cẩn thận, mã này giả định hình ảnh là "ngang" (ngang)
Alex.

8

Đây là một ví dụ hoàn chỉnh về cách tạo một hình ảnh nhỏ hơn (hình thu nhỏ). Đoạn mã này thay đổi kích thước Hình ảnh, xoay hình ảnh khi cần thiết (nếu điện thoại được giữ theo chiều dọc) và đệm hình ảnh nếu bạn muốn tạo hình vuông. Đoạn mã này tạo ra một JPEG, nhưng nó có thể dễ dàng được sửa đổi cho các loại tệp khác. Ngay cả khi hình ảnh nhỏ hơn kích thước tối đa cho phép, hình ảnh vẫn sẽ được nén và độ phân giải của nó được thay đổi để tạo ra những hình ảnh có cùng dpi và mức độ nén.

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

Đối với người dùng asp.net một ví dụ nhỏ về cách tải lên tệp, thay đổi kích thước tệp và hiển thị kết quả trên trang.

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

Tôi thích ví dụ mã này và chọn sử dụng nó. Tuy nhiên, bất kể tôi đã thực hiện những thay đổi nào đối với các tùy chọn khác nhau (imageResolution ,ressionLevel, CompositingMode, CompositingQuality, SmoothingMode, InterpolationMode, PixelOffsetMode), kích thước tệp hình ảnh chỉ giảm một lượng nhỏ. Và tôi chưa bao giờ thấy bất kỳ sự khác biệt nào trong hình ảnh được tạo ra. Cuối cùng, tôi đã chọn lưu hình ảnh vào một tệp thay vì luồng bộ nhớ và có thể thấy những thay đổi mạnh mẽ. Đối với bất kỳ ai sử dụng tính năng này, việc lưu vào luồng bộ nhớ không ảnh hưởng đến hình ảnh trả về.
BLaminack

1

Đây là một ví dụ để chuyển đổi hình ảnh có độ phân giải cao thành kích thước hình thu nhỏ-

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

Nguồn- http://iknowledgeboy.blogspot.in/2014/03/c-creating-thumbnail-of-large-image-by.html

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.