Saving An image,A generic error occurred in GDI+ - c#

i get an
A generic error occurred in GDI+
exception when I call img.Save(path, jpegCodec, encoderParams);
here is all of the code :
private Image img;
private void button1_Click(object sender, EventArgs e)
{
this.img = Image.FromFile(#"path");
pictureBox1.Image = img;
if (img.Height < pictureBox1.Height && img.Width < pictureBox1.Width)
{
this.pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
}
Graphics g = Graphics.FromImage(img);
Font font=new Font("Arial",16);
SolidBrush brush = new SolidBrush(Color.Black);
brush.Color = Color.FromArgb(255, 0, 0, 255);
g.DrawString("myName", font, brush, img.Width - 178, img.Height-105);
}
private void button2_Click(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(img);
saveJpeg(#"path", bitmap, 85L);
}
private void saveJpeg(string path, Bitmap img, long quality)
{
// Encoder parameter for image quality
EncoderParameter qualityParam =new EncoderParameter(Encoder.Quality, quality);
// Jpeg image codec
ImageCodecInfo jpegCodec = getEncoderInfo("image/jpeg");
if (jpegCodec == null)
return;
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
//img.Save(path, jpegCodec, encoderParams);
img.Save(path, 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;
}
Would you help me?

As long as the image object exists that was created by loading the image from the file, the file is in use. You can't save an image with the same name while the file is in use.
Instead of using Image.FromFile to load the image, open a file stream and use Image.FromStream to create the image, then close the file stream. That way the file is no longer in use, and you can replace it.

public ActionResult CropImage(string hdnx, string hdny, string hdnw, string hdnh)
{
string fname = "pool.jpg";
string fpath = Path.Combine(Server.MapPath("~/images"), fname);
Image oimg = Image.FromFile(fpath);
Rectangle cropcords = new Rectangle(
Convert.ToInt32(hdnx),
Convert.ToInt32(hdny),
Convert.ToInt32(hdnw),
Convert.ToInt32(hdnh));
string cfname, cfpath;
Bitmap bitMap = new Bitmap(cropcords.Width, cropcords.Height,img.PixelFormat);
Graphics grph = Graphics.FromImage(bitMap);
grph.DrawImage(oimg, new Rectangle(0, 0, bitMap.Width, bitMap.Height), cropcords, GraphicsUnit.Pixel);
cfname = "crop_" + fname;
cfpath = Path.Combine(Server.MapPath("~/cropimages"), cfname);
bitMap.Save(cfpath);
return Json("success",JsonRequestBehavior.AllowGet);
}

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?

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

My image is not compressing

Loading code from filesystem:
System.Drawing.Image image = System.Drawing.Image.FromFile(<location of original image>););
Loading code from browser request:
var memoryStream = new MemoryStream();
using (memoryStream)
{
System.Web.HttpContext.Current.Request.Files[upload].InputStream.CopyTo(memoryStream);
memoryStream.ToArray();
}
byte[] bytes = memoryStream.GetBuffer();
// Get the image from the server
System.Drawing.Image image = new System.Drawing.Bitmap( System.Web.HttpContext.Current.Request.Files[upload].InputStream );
Resize image call:
System.Drawing.Image image = this.ResizeImage(
image,
originalImagePath,
ImageSizeType.Original,
null,
null)
Save image call:
image.Save(<location to save>);
The code that doesn't compress the image:
private System.Drawing.Image ResizeImage(System.Drawing.Image image, string filePath, string sizeType, int? _width, int? height )
{
...
System.Drawing.Bitmap b = new System.Drawing.Bitmap(width, resizeHeight);
b.SetResolution(72, 72);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage((System.Drawing.Image)b);
g.CompositingQuality = CompositingQuality.HighSpeed;
//g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.InterpolationMode = InterpolationMode.Low;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.DrawImage(image, 0, 0, width, resizeHeight);
g.Dispose();
return (System.Drawing.Image)b;
}
No matter what I do to this image, when it saves, it saves at a really high kb.
For example... a jpg of 1024 x 768 # 300kb becomes 600 x 400 # 800kb
What am I doing wrong?
As Magnus rightly said, the drawing to the canvas makes no difference to size... of file...
It was the save file part that was being all noob... This is what it should be:
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;
}
...
if( mimeType.ToLower() == "image/jpeg")
{
ImageCodecInfo jpgEncoder = this.GetEncoderInfo("image/jpeg")
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 80L);
myEncoderParameters.Param[0] = myEncoderParameter;
image.Save(systemFilePath, jpgEncoder, myEncoderParameters);
}
else
{
image.Save(systemFilePath);
}

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

save pictures to harddrive

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

Categories

Resources