19

I need to create a thumbnail image from the original image and need to save both images in the local folder. I am using html file control for uploading the image

<input type="file" class="form-control" asp-for="ImageName" name="ProductImage" id="ProductImage">

And by the time of form submission I am getting it as IFromFile

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Guid id, ProductDTO product, IFormFile 
    ProductImage)
{
    if (ModelState.IsValid)
    {
        byte[] fileBytes;
        using (var ms = new MemoryStream())
        {
            ProductImage.CopyTo(ms);
            fileBytes = ms.ToArray();
        }
    }
}

I have converted it to byte[] and passing it to one of my method for saving it. Here I need the thumbnail of the particular image

What I have tried so far is to add the package Install-Package System.Drawing.Common -Version 4.5.1

And created a method for converting the image

public string ErrMessage;

public bool ThumbnailCallback()
{
    return false;
}
public Image GetReducedImage(int Width, int Height, Image ResourceImage)
{
    try
    {
        Image ReducedImage;

        Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);

        ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero);

        return ReducedImage;
    }
    catch (Exception e)
    {
        ErrMessage = e.Message;
        return null;
    }
}

But the method which I created is accepting a type of Image So little confused here, not sure how can we do that with byte[]. Also I am not getting the image local path from the IFileForm so i cannot directly give the path too.

Can someone help me to resolve this ?

Ciarán Bruen
  • 5,221
  • 13
  • 59
  • 69
Arunprasanth K V
  • 20,733
  • 8
  • 41
  • 71

1 Answers1

25

Finally got the answer

Installed System.Drawing.Common -Version 4.5.1 package

Open the package manager and run the below code for installing the package

Install-Package System.Drawing.Common -Version 5.0.2

Then use the below code:

using System.Drawing;

var stream = ProductImage.OpenReadStream();

var newImage = GetReducedImage(32,32,stream);
newImage.Save("path+filename");

public Image GetReducedImage(int width, int height, Stream resourceImage)
{
    try
    {
        var image = Image.FromStream(resourceImage);
        var thumb = image.GetThumbnailImage(width, height, () => false, IntPtr.Zero);

        return thumb;
    }
    catch (Exception e)
    {
        return null;
    }
}
David Noreña
  • 3,951
  • 1
  • 28
  • 43
Arunprasanth K V
  • 20,733
  • 8
  • 41
  • 71
  • 3
    Copying to a new memory stream is inefficient. Change your method to simply accept the `Stream` base type and pass in your file stream directly. – Chris Pratt Jan 07 '19 at 15:25
  • @ChrisPratt Edited the answer, can you please have a look into that and let me know if any more changes are needed ? – Arunprasanth K V Jan 07 '19 at 16:08
  • 2
    You should wrap `OpenReadStream()` in a `using` block. – Chris Pratt Jan 07 '19 at 16:45
  • What if I want to just pass in only height or width and retain the images aspect ratio? – tnk479 Jul 13 '20 at 19:06
  • 1
    Beware that on Linux this library is using libgdiplus. And user can craft a file that will cause exterme memory usage on your server (for example a tiff with 1000 pages that will be only 100Kb ) – norekhov Oct 09 '20 at 09:23
  • Late to the party, but there are some serious remarks to be aware of: https://learn.microsoft.com/en-us/dotnet/api/system.drawing?view=net-6.0#remarks – Phate01 Dec 28 '22 at 16:25