save pictures to harddrive - c#

I'm trying to resize and safe a picture I've done some research and tried to get sommething working. Almost everythin works but the saving gaves me an invalid argument exception.
This is what I have:
private void ResizeImage(Image image)
{
int maxWidth = 100;
int maxHeight = 100;
int imageWidth = image.Size.Width;
int imageHeight = image.Size.Height;
double maxRatio = (double)maxWidth / (double)maxHeight;
double picRatio = (double)imageWidth / (double)imageHeight;
Image newImage = null;
if (maxRatio > picRatio && imageWidth > maxWidth)
{
newImage = new Bitmap(image, new System.Drawing.Size(Convert.ToInt32(maxWidth / picRatio), maxHeight));
}
else if (maxRatio < picRatio && imageHeight > maxHeight)
{
newImage = new Bitmap(image, new System.Drawing.Size(maxWidth, Convert.ToInt32(maxHeight / picRatio)));
}
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality,1);
// Jpeg image codec
ImageCodecInfo jpegCodec = this.getEncoderInfo("image/jpeg");
if(jpegCodec != null){
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
newImage.Save(#".\temp\pdf\photos\test.jpg",jpegCodec,encoderParams);
}
}
private ImageCodecInfo getEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
{
if (codecs[i].MimeType == mimeType)
{
return codecs[i];
}
}
return null;
}
But when I try to run it, it gives me an invalid argument exception on newImage.save()

According to MSDN, encoder quality parameter should be a 64-bit (long) value. Change this line:
var qualityParam = new EncoderParameter(Encoder.Quality, 1);
to
var qualityParam = new EncoderParameter(Encoder.Quality, 1L);

Related

System.Drawing.Imaging.Encoder.Quality file size changing strangely

I am trying out working with images and i came up to some strange behavior when using Encoder.Quality
I am having code like this:
try
{
Image myImage = Image.FromStream(file.OpenReadStream());
string final = "";
MemoryStream ts = new MemoryStream();
SaveJpeg(ts, myImage, 100);
final += (ts.Capacity * 0.0009765625).ToString("0") + ", ";
for (int i = 0; i <= 10; i++)
{
MemoryStream testStream = new MemoryStream();
SaveJpeg(testStream, myImage, i * 10);
final += (testStream.Capacity * 0.0009765625).ToString("0") + ", ";
}
return Json(final);
}
catch (Exception ex)
{
return View("Error", ex.ToString());
}
public static void SaveJpeg(string path, Image img, int quality)
{
if (quality < 0)
quality = 0;
if (quality > 100)
quality = 100;
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, quality);
// JPEG image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
}
public static void SaveJpeg(Stream stream, Image img, int quality)
{
if (quality < 0)
quality = 0;
if (quality > 100)
quality = 100;
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, quality);
// JPEG image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(stream, jpegCodec, encoderParams);
}
/// <summary>
/// Returns the image codec with the given mime type
/// </summary>
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
It is asp.net core but i think that dosn't matter.
What matters here is that file i upload is "jpg" and it's size is 201kb but output from this code is 512, 29, 41, 53, 128, 128, 128, 128, 128, 128, 256, 512, (first number is quality 100, others are 0, 10, 20... 100)
When i store it into MemoryStream without changing quality i get same file size as my file.
Here i have two questions.
Is quality level 90-100 somehow "enchancing" image quality?
Why is image size from level 40-90 all same size, does it make any difference?

c# How to resize any image to specific kilobytes while retaining image type

I've seen a ton of stackoverflow articles for reducing image size, but none of them maintain the original image type (or so I've found). They usually have steps to reduce pixel dimensions, reduce image quality, and convert to a specific type of image (usually jpeg).
I have a group of images that I need to resize. They have various image types, and the filenames are all stored in a database, which makes converting from one image type to another somewhat problematic. I can't just change the filename from png to jpg because then the database won't point at a real file.
Doe anyone have an example of how to resize / reduce images to '256 kilobytes' and maintain the original image type?
For examples, here is the code I'm currently fiddling with.
public static byte[] ResizeImageFile(Image oldImage, int targetSize) // Set targetSize to 1024
{
Size newSize = CalculateDimensions(oldImage.Size, targetSize);
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
{
using (Graphics canvas = Graphics.FromImage(newImage))
{
canvas.SmoothingMode = SmoothingMode.AntiAlias;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
MemoryStream m = new MemoryStream();
newImage.Save(m, ImageFormat.Jpeg);
return m.GetBuffer();
}
}
}
Maybe there is a way I can get file fileinfo or mime type first and then switch on the .Save for the type of image?
Here is what I came up with (based on some examples that I found online that weren't 100% complete.
private void EnsureImageRequirements(string filePath)
{
try
{
if (File.Exists(filePath))
{
// If images are larger than 300 kilobytes
FileInfo fInfo = new FileInfo(filePath);
if (fInfo.Length > 300000)
{
Image oldImage = Image.FromFile(filePath);
ImageFormat originalFormat = oldImage.RawFormat;
// manipulate the image / Resize
Image tempImage = RefactorImage(oldImage, 1200); ;
// Dispose before deleting the file
oldImage.Dispose();
// Delete the existing file and copy the image to it
File.Delete(filePath);
// Ensure encoding quality is set to an acceptable level
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
// Set encoder to fifty percent compression
EncoderParameters eps = new EncoderParameters
{
Param = { [0] = new EncoderParameter(Encoder.Quality, 50L) }
};
ImageCodecInfo ici = (from codec in encoders where codec.FormatID == originalFormat.Guid select codec).FirstOrDefault();
// Save the reformatted image and use original file format (jpeg / png / etc) and encoding
tempImage.Save(filePath, ici, eps);
// Clean up RAM
tempImage.Dispose();
}
}
}
catch (Exception ex)
{
this._logger.Error("Could not resize oversized image " + filePath, ex);
}
}
private static Image RefactorImage(Image imgToResize, int maxPixels)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
int destWidth = sourceWidth;
int destHeight = sourceHeight;
// Resize if needed
if (sourceWidth > maxPixels || sourceHeight > maxPixels)
{
float thePercent = 0;
float thePercentW = 0;
float thePercentH = 0;
thePercentW = maxPixels / (float) sourceWidth;
thePercentH = maxPixels / (float) sourceHeight;
if (thePercentH < thePercentW)
{
thePercent = thePercentH;
}
else
{
thePercent = thePercentW;
}
destWidth = (int)(sourceWidth * thePercent);
destHeight = (int)(sourceHeight * thePercent);
}
Bitmap tmpImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(tmpImage);
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return tmpImage;
}

How to edit/ reduce/ resize image C#?

In my project, I need to resize the image (e.g.1080 to 720), reduce the file size (may be resolution, 0-100) which is uploaded by client, so that they can then download it.
I can reduce the file size (by resolution) in C#, but not scale and resize. Can anyone tell me how to do that, even using APIs or frameworks.
My reduce resolution code in C#: (from this post)
public static void Saveimage(string path, Image img, int quality)
{
if (quality < 0 || quality > 100)
throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, quality);
string imageType = GetImageFormat(img);
ImageCodecInfo imageCodec = GetEncoderInfo(imageType);
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, imageCodec, encoderParams);
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
public static string GetImageFormat(Image img)
{
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
return "image/jpeg";
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
return "image/png";
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
return "image/tiff";
else
return "image/jpeg";
}
Call:
Saveimage(#"C:\mypath", myImage, 1);

Compressing pictures in asp.net

i want to compress pictures in asp.net but the code i use those not fully compressing the files as soon are still very huge. How can i further reduce the size?
string directory = Server.MapPath("~/listingImages/" + date + filename);
// Create a bitmap of the conten t of the fileUpload control in memory
Bitmap originalBMP = new Bitmap(AsyncFileUpload1.FileContent);
// Calculate the new image dimensions
decimal origWidth = originalBMP.Width;
decimal origHeight = originalBMP.Height;
decimal sngRatio = origHeight / origWidth;
int newHeight = 300; //hight in pixels
decimal newWidth_temp = newHeight / sngRatio;
int newWidth = Convert.ToInt16(newWidth_temp);
// Create a new bitmap which will hold the previous resized bitmap
Bitmap newBMP = new Bitmap(originalBMP, newWidth, newHeight);
// Create a graphic based on the new bitmap
Graphics oGraphics = Graphics.FromImage(newBMP);
// Set the properties for the new graphic file
oGraphics.SmoothingMode = SmoothingMode.AntiAlias;
oGraphics.InterpolationMode = InterpolationMode.Bicubic;
// Draw the new graphic based on the resized bitmap
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
// Save the new graphic file to the server
newBMP.Save(Server.MapPath("~/listingImages/" + date + filename));
Try setting the compressipn using this:
public static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
} return null;
}
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(Encoder.Quality, (long)70);
ImageCodecInfo ici = GetEncoderInfo("image/jpeg");
newBMP.Save(Server.MapPath("~/listingImages/" + date + filename), ici, ep);
Check this link for more details: https://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoder.quality%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396.
Maybe you should specify image-format:
newBMP.Save(Server.MapPath("~/listingImages/" + date + filename), System.Drawing.Imaging.ImageFormat.Png);

Getting error when try to save file in Asp.net Using c#

This is the error i am getting right now
System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+. at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
i am using this same code on other website in same machine and there is no problem i really don't know what's going on please give me solution
here is my code
double newHeight = 0;
double newWidth = 0;
double scale = 0;
//create new image object
Bitmap curImage = new Bitmap(filePath);
//Determine image scaling
if (curImage.Height > curImage.Width)
{
scale = Convert.ToSingle(size) / curImage.Height;
}
else
{
scale = Convert.ToSingle(size) / curImage.Width;
}
if (scale < 0 || scale > 1) { scale = 1; }
//New image dimension
newHeight = Math.Floor(Convert.ToSingle(curImage.Height) * scale);
newWidth = Math.Floor(Convert.ToSingle(curImage.Width) * scale);
//Create new object image
Bitmap newImage = new Bitmap(curImage, Convert.ToInt32(newWidth), Convert.ToInt32(newHeight));
Graphics imgDest = Graphics.FromImage(newImage);
imgDest.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
imgDest.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
imgDest.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
imgDest.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
EncoderParameters param = new EncoderParameters(1);
param.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
//Draw the object image
imgDest.DrawImage(curImage, 0, 0, newImage.Width, newImage.Height);
//Save image file
newImage.Save(saveFilePath, info[1], param);
//Dispose the image objects
curImage.Dispose();
newImage.Dispose();
imgDest.Dispose();
}
You will get a GDI error message if the account you're running under cannot save to the path at saveFilePath on this line:
newImage.Save(saveFilePath, info[1], param);

Categories

Resources