Resizing and creating image thumbnail in ASP.NET-Core 2.2

3k Views Asked by At

I am trying to create a thumbnail image in asp.net-core 2.2 application but I keep getting the above error whenever it gets to the point of creating the thumbnail.

The main image creates and stores fine but it is not able to create the thumbnail. Please I will appreciate any guide to resolve the error

Here are my methods for storing the uploaded image. This one works as expected

using LazZiya.ImageResize;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace eSchool.Models.Utilities
{
public  class FileUploadHelper
{
    private readonly IHostingEnvironment host;
    public FileUploadHelper(IHostingEnvironment _host)
    {
        host = _host;
    }

    public async Task<string> SaveFileAsync(IFormFile file, string pathToUplaod)
    {
        string webroot=host.WebRootPath;

        string DesiredDirectoryLocation = Path.Combine(webroot,pathToUplaod);
        if(!Directory.Exists(DesiredDirectoryLocation))
        {
            Directory.CreateDirectory(DesiredDirectoryLocation);
        }

        string imageUrl = string.Empty;
        var filename = Path.GetRandomFileName();
        var newfilename = CreateUniqueFileName(file);
        string pathwithfileName = DesiredDirectoryLocation + "/" + newfilename;
        using (var fileStream = new FileStream(pathwithfileName, FileMode.Create))
        {
            await file.CopyToAsync(fileStream);
        }

        imageUrl = newfilename;

        return imageUrl;
    }

I have tried two different methods to create the thumbnail but either of them gives the above error

Here are the two methods.

The first one is this:

public string CreateThumbImage(IFormFile uploadedFile, string desiredThumbPath,string desiredThumbFilename, int desiredThumbWidth, int desiredThumbHeight)
    {
        try
        {
            Stream filestream = uploadedFile.OpenReadStream();
            Image thumbnailStream = Image.FromStream(filestream);
            Image thumbnailImage = thumbnailStream.GetThumbnailImage(desiredThumbWidth, desiredThumbHeight, () => false, IntPtr.Zero);

            string webroot = host.WebRootPath;

            string DesiredDirectoryLocation = Path.Combine(webroot, desiredThumbPath);

            if (!Directory.Exists(DesiredDirectoryLocation))
            {
                Directory.CreateDirectory(DesiredDirectoryLocation);
            }

            string thumbFullPathName = desiredThumbPath + "/" + desiredThumbFilename;
            thumbnailImage.Save(thumbFullPathName);

            return thumbFullPathName;
        }
        catch
        {
            throw;
        }

    }

And the second one is this:

public void ResizeImage(IFormFile uploadedFile, string desiredThumbPath, int desiredWidth=0, int desiredHeight=0)
    {
        if (uploadedFile.Length > 0)
        {
            using (var stream = uploadedFile.OpenReadStream())
            {
                var uploadedImage = System.Drawing.Image.FromStream(stream);

                //decide how to scale dimensions
                if (desiredHeight == 0 && desiredWidth > 0)
                {
                    var img = ImageResize.ScaleByWidth(uploadedImage, desiredWidth); // returns System.Drawing.Image file
                    img.SaveAs(desiredThumbPath);
                }
                else if(desiredWidth == 0 && desiredHeight > 0)
                {
                    var img = ImageResize.ScaleByHeight(uploadedImage, desiredHeight); // returns System.Drawing.Image file
                    img.SaveAs(desiredThumbPath);
                }
                else
                {
                    var img = ImageResize.Scale(uploadedImage, desiredWidth,desiredHeight); // returns System.Drawing.Image file
                    img.SaveAs(desiredThumbPath);
                }

            }
        }
        return;
    }

And this is where I call the methods:

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {

        FileUploadHelper uploadHelper = new FileUploadHelper(_host);
        if (EmailValidation.EmailExists(model.EmailAddress,_context))
        {
            ModelState.AddModelError("EmailAddress", "This email address is already registered with us.");
        }

        if (model.Photo != null)
        {
            string[] extensions = new string[] { ".jpeg",".jpg", ".gif", ".png" };

            ///Validate the type of the image file being uploaded
            ResponseMsg fileTypeValidated = uploadHelper.ValidateFileExtension(model.Photo, extensions);
            if (!fileTypeValidated.ResponseStatus)
            {
                ModelState.AddModelError("Photo", fileTypeValidated.ResponseDescription);
            }

            ///Validate the size of the image file being uploaded
            ResponseMsg fileSizeValidated = uploadHelper.ValidateFilesize(model.Photo, 1);
            if (!fileSizeValidated.ResponseStatus)
            {
                ModelState.AddModelError("Photo", fileSizeValidated.ResponseDescription);
            }
        }

        if (ModelState.IsValid)
        {
            try
            {
                Instructor instructor = new Instructor
                {
                    Surname = model.Surname,
                    OtherNames = model.Othernames,
                    Email = model.EmailAddress,
                    UserName = model.EmailAddress,
                    PhoneNumber = model.PhoneNumber,
                    Gender = model.Gender,
                    StateId = model.ResidenceState,
                    LgaId = model.ResidenceLga,
                    DateOfBirth = model.DateOfBirth,
                    TimeRegistered = DateTime.Now
                };

                var photo = await uploadHelper.SaveFileAsync(model.Photo,"images/instructors");
                //Create image thumbnail for the instructor photo
                var photo_thumbnail = "images/instructors/thumbs/" + photo;
                uploadHelper.CreateThumbImage(model.Photo, "images/instructors/thumbs/", photo, 100, 100);...

Please help me if you can point out where I am missing the right path or a better way to handle image thumbnail creation in ASP.NET-Core 2.* to fix the error.

Regards

2

There are 2 best solutions below

0
On BEST ANSWER

The error came from the path of the thumbnail. The path given in the ResizeImage method does not indicate the filename of the thumbnail image. That is where the generic GDI+ error was coming from.

So using the ResizeImage method works when the path of the resized image (including the image filename) is correctly passed to the SaveAs method. Here is the working method:

public void ResizeImage(IFormFile uploadedFile, string desiredThumbPath, int desiredWidth=0, int desiredHeight=0)
    {
        string webroot = host.WebRootPath;

        if (uploadedFile.Length > 0)
        {
            using (var stream = uploadedFile.OpenReadStream())
            {
                var uploadedImage = System.Drawing.Image.FromStream(stream);

                //decide how to scale dimensions
                if (desiredHeight == 0 && desiredWidth > 0)
                {
                    var img = ImageResize.ScaleByWidth(uploadedImage, desiredWidth); // returns System.Drawing.Image file
                    img.SaveAs(Path.Combine(webroot,desiredThumbPath));
                }
                else if(desiredWidth == 0 && desiredHeight > 0)
                {
                    var img = ImageResize.ScaleByHeight(uploadedImage, desiredHeight); // returns System.Drawing.Image file
                    img.SaveAs(Path.Combine(webroot,desiredThumbPath));
                }
                else
                {
                    var img = ImageResize.Scale(uploadedImage, desiredWidth,desiredHeight); // returns System.Drawing.Image file
                    img.SaveAs(Path.Combine(webroot,desiredThumbPath));
                }
            }
        }
        return;
    }

And the implementation is as follows:

//Create image thumbnail for the instructor photo
                var photo_thumbnail = "images/instructors/thumbs/" + photo;
                uploadHelper.ResizeImage(model.Photo, photo_thumbnail, 100);

Remember to include the following using statement in the parent class of uploadHelper that houses the ResizeImage method as follows:

using LazZiya.ImageResize;

Meanwhile, LazZiya.ImageResize is nugget package for managing image resizing in asp.net-core 2.1 See the github link for it Github link for LazZiya image nugget

So, that solves your image resizing problem in asp.net-core

Regards

1
On

Once file uploaded/saved to server. You can use following ASP.NET core middleware to serve image thumbnails.

https://github.com/osprakash/ImageThumbnail-aspnetcore

Configure middleware in startup.cs and pass thumbnail size like below :

Disclaimer : i"m the author of above open source package.