4

I am using .NET Core 2.2. In my code, I am using IFormFile to upload images. How can I compress the image size (to KB) just before it is uploaded to the server ? I search for solutions but those answers were related to Bitmap but since I am using IFormFile therefore I want solution related to it.

I will internally check the image size and if its size is up to 700KB, I don't want to compress. But if it is higher, then I want to compress and upload. Sample codes would be very useful

I tried to use Magick.NET package. How can I make IFormFile to MagickImage type?

foreach(IFormFile photo in Images)  
{
  using (MagickImage mi = photo)  // Cannot implicitly convert type 
                                  //Microsoft.AspNetCore.Http.IFormFile to ImageMagick.MagickImage
   {
      mi.Format = Image.Jpeg;
      mi.Resize(40, 40);
      mi.Quality = 10;
      mi.Write(imageFile);
   }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
Vim
  • 161
  • 2
  • 3
  • 11
  • Is the `before upload` you mentioned means 'Before uploading from the browser to the server' or means 'Bofore uploading to another server after uploaded to your current server'? If you want to compress a file before it uploads, it is not where the server written by C# can handle. You shall search for some javascript solutions. – Anduin Xue Dec 08 '19 at 16:08
  • 1) You cannot do any operation on the image *before* it's uploaded, at least with C#. 2) You cannot control the size explicitly: only the quality. You could do some sort of recursive algorithm where you incrementally lower the quality from max until the file size is within an acceptable range, but it could potentially take multiple recursions and depending on the uploaded file size, might cause perf issues. – Chris Pratt Dec 09 '19 at 14:13

1 Answers1

17

I have used Magick.NET library which is available for both .NET and .NET Core to compress images. Refer to its documentation for more details.

In your case you either need to save the image temporarily somewhere and use the path (similar to my example), or convert it to an array of byte in memory and read that since it accept Byte[]

     using (MagickImage image = new MagickImage(@"YourImage.jpg"))
       {
           image.Format = image.Format; // Get or Set the format of the image.
           image.Resize(40, 40); // fit the image into the requested width and height. 
           image.Quality = 10; // This is the Compression level.
           image.Write("YourFinalImage.jpg");                 
        }
Benjamin
  • 3,499
  • 8
  • 44
  • 77
  • The problem is, I cannot convert type IFormFile to MagickImage type. I have updated the question. Could you help about the correct way to do it ? – Vim Dec 08 '19 at 15:01
  • 1
    using (MagickImage mi = new MagickImage(photo)) – Joel Wiklund Dec 08 '19 at 15:35
  • 1
    @Benjamin Since image uploaded can be of different sizes, and if i keep image.Quality = 10 (or any other number) then although it will decrease the image size (1MB was brought down to 83KB which is good), but is there a way to make it below certain size like I would be happy to have converted image size upto 700KB maximum (with original resolution) whether the original size is 5MB or 10MB or 20MB. I don't want images to be 83KB because the quality would be compromised too much. I don't want high quality image but not too low like 83KB quality. – Vim Dec 08 '19 at 17:22