A Generic error occurred in GDI+ from picture of Ipad Air - c#

Hi I have this error when a try to upload a picture downloaded via email from an Ipad Air Camera(JPG)
A Generic error occurred in GDI+
Here is the code, anyone can helps me? All the pictures are saving good except from this Ipad Air.
var pic = System.Web.HttpContext.Current.Request.Files[0];// canvi per Vendor/fileuploadmaster
Bitmap bmp = new Bitmap(pic.InputStream);
DateTime dtaken;
PropertyItem propItem;
try {
propItem = bmp.GetPropertyItem(36867);
string sdate = System.Text.Encoding.UTF8.GetString(propItem.Value).Trim();
string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" ")));
string firsthalf = sdate.Substring(0, 10);
firsthalf = firsthalf.Replace(":", "-");
sdate = firsthalf + secondhalf;
dtaken = DateTime.Parse(sdate);
}
catch {
dtaken = DateTime.Now;
}
//Fecha de última modificacion
//PropertyItem propItem = bmp.GetPropertyItem(306);
var newFilePath = ConfigurationManager.AppSettings["PathTmpPhotos"].ToString();
var FechaString = dtaken.ToString("yyMMddHHmmss");
var newFileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + visitBrandId.ToString("D10") + "_" + FechaString + "_" + pic.FileName;
var tmpFilePath = newFilePath + newFileName;
pic.SaveAs(tmpFilePath);
var img = FileUtilities.ResizePhoto(newFilePath, newFileName, 800, 600);
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
// Create an Encoder object based on the GUID
// for the Quality parameter category.
Encoder myEncoder = Encoder.Quality;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);
// 0L = NO Quality // 100L = High Quality
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;
img.Save(Path.Combine(newFilePath, newFileName), jpgEncoder, myEncoderParameters);
//img.Save(Path.Combine(newFilePath, newFileName));

The solution was in the ResizePhoto.
When the picture was taken with the mobile, is under 800x600 size, so this function cant resize the picture to a bigger size.
So, the solution was this:
var img = FileUtilities.ResizePhoto(newFilePath, newFileName, 300, 200);
Because dont exist any picture taken with the mobile smaller than 300x200
Regards

Related

A generic error occurred in GDI+ when scaling an image

I'm trying to scale an image and save that image to a new location. Now i'm having this error "A generic error occurred in GDI+ at System.Drawing.Image.Save".
I've found a couple of answers on stackoverflow, unfortunately without any results.
public static void SaveImageScaled(String imagePath, string destPath, Size newSize, String filename)
{
using (Bitmap bmpOriginal = (Bitmap)Image.FromFile(imagePath))
using (Bitmap bmpResized = new Bitmap(newSize.Width, newSize.Height))
using (Graphics g = Graphics.FromImage(bmpResized))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(
bmpOriginal,
new Rectangle(Point.Empty, bmpResized.Size),
new Rectangle(Point.Empty, bmpOriginal.Size),
GraphicsUnit.Pixel);
// Lower the quality;
long qualityPercentage = 75L;
ImageCodecInfo[] myImageCodecInfoList = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo myImageCodecInfo = myImageCodecInfoList.Where(x => x.FormatID == bmpOriginal.RawFormat.Guid).First();
Encoder myEncoder = Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, qualityPercentage);
myEncoderParameters.Param[0] = myEncoderParameter;
if (!Directory.Exists(destPath))
Directory.CreateDirectory(destPath);
// ERROR
bmpResized.Save(destPath + filename, myImageCodecInfo, myEncoderParameters);
}
}
This code created a directory with insufficient write-acces. Changed the permissions on a higher directory level, and solved the issue.
if (!Directory.Exists(destPath))
Directory.CreateDirectory(destPath);

ASP.NET uploading a file to Amazon S3

I am in the process of uploading images to Amazon S3, however i keep getting the error "Please specify either a Filename, provide a FileStream or provide a ContentBody to PUT an object into S3."
Basically i am uploading an image from a fileupload control and then hitting the code below. It uploads locally fine, but not to Amazon. The Credentials are alright so it only errors when it comes to uplaoding.
Can anyone see why this is happening please?
protected void uploadImg(int prodId, int prodFormat)
{
if (imgPack.HasFile)
{
string fileExt = Path.GetExtension(imgPack.PostedFile.FileName);
string filename = "img" + prodId + ".jpg";
// Specify the upload directory
string directory = Server.MapPath(#"\images\packshots\");
if (fileExt == ".jpeg" || fileExt == ".jpg" || fileExt == ".png")
{
if (packUK.PostedFile.ContentLength < 716800)
{
// Create a bitmap of the content of the fileUpload control in memory
Bitmap originalBMP = new Bitmap(packUK.FileContent);
// Calculate the new image dimensions
decimal origWidth = originalBMP.Width;
decimal origHeight = originalBMP.Height;
decimal sngRatio = origHeight / origWidth;
int newHeight = 354; //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.HighQualityBicubic;
// Draw the new graphic based on the resized bitmap
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
// Save the new graphic file to the server
string accessKey = "KEY HERE";
string secretKey = "KEY HERE";
AmazonS3 client;
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
{
PutObjectRequest request = new PutObjectRequest();
request.BucketName="MyBucket";
request.CannedACL = S3CannedACL.PublicRead;
request.Key = "images/" + filename;
S3Response response = client.PutObject(request);
}
//newBMP.Save(directory + filename);
// Once finished with the bitmap objects, we deallocate them.
originalBMP.Dispose();
newBMP.Dispose();
oGraphics.Dispose();
}
}
else
{
notifybar.Attributes.Add("style", "display:block;");
notifybar.Attributes.Add("class", "failed");
notifyText.Text = "Error Text Here";
}
}
else
{
notifybar.Attributes.Add("style", "display:block;");
notifybar.Attributes.Add("class", "failed");
notifyText.Text = "Error Text Here";
}
}
You need to assign File or InputStream property of PutObjectRequest object. The code fragment should look like this one:
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
{
var stream = new System.IO.MemoryStream();
originalBMP.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
PutObjectRequest request = new PutObjectRequest();
request.InputStream = stream;
request.BucketName="MyBucket";
request.CannedACL = S3CannedACL.PublicRead;
request.Key = "images/" + filename;
S3Response response = client.PutObject(request);
}

Bitmap class parameter not valid

I pass an array to a method and I use a foreach loop. The parameter I'm passing to new Bitmap() is not valid for some reason. I get the error "Parameter is not valid." The parameter is a string path (as it should be).
Can anyone tell me what's wrong?
If I highlight the parameter name, this is what it shows me, which seems to be correct:
"C:\Reinstatement Image Transporter\Image Processing\NYH004402800_REINSTMT_0e2837ae.jpg"
public static void CompressPictures(string[] processingFiles)
{
string originalFileName = "";
foreach (string file in processingFiles)
{
//I'm getting the error right here:
Bitmap pic = new Bitmap(file);
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
Encoder myEncoder = Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameter = new EncoderParameter(myEncoder, 0L);
myEncoderParameters.Param[0] = myEncoderParameter;
originalFileName = Path.GetFileNameWithoutExtension(file.Remove(file.Length - 1, 1));
pic.Save(AppVars.ProcessingPolicyImagesFolder + originalFileName, jgpEncoder, myEncoderParameters);
}
}
(Per the comments on the question above: It was a simple FileNotFound error.)

Upload image to c# server from iPhone

I want to upload a image to my server form iPhone
To upload image my code is
UIImage *image = [UIImage imageNamed:#"bg_DName.png"];
NSMutableData *imageData = (NSData*)UIImagePNGRepresentation(image);
NSString *string = [NSString stringWithFormat:#"http://myServer/HeritageWebServices/Service.asmx/testuploadimage"];
[self setRequest1:[ASIFormDataRequest requestWithURL:[NSURL URLWithString:string]]];
[request1 setPostValue:#"test" forKey:#"value1"];
[request1 setPostValue:#"test" forKey:#"value2"];
[request1 setPostValue:#"test" forKey:#"value3"];
[request1 setTimeOutSeconds:20];
[request1 setDelegate:self];
[request1 setDidFailSelector:#selector(uploadFailed:)];
[request1 setDidFinishSelector:#selector(uploadFinished:)];
[request1 setPostBody:imageData];
// NSLog(#"image %#",imageData);
[request1 setData:imageData withFileName:#"photo.png" andContentType:#"image/png" forKey:#"photo"];
[request1 startAsynchronous];
With the above code i am not able upload image.
UIImage *image = [UIImage imageNamed:#"bg.png"];
NSData *imageData = UIImagePNGRepresentation(image);
//NSLog(#"imageData %#",imageData);
NSString *dt = [[imageData description] stringByTrimmingCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
dt = [dt stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *string = [NSString stringWithFormat:#"http://myServer/HeritageWebServices/Service.asmx/testuploadimage?image=%#",dt];
// NSLog(#"urlstring %#",string);
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:string]];
//
[request startAsynchronous];
If i try like this i can upload small image but not large images.Here i am sending the image in the request parameter as string.
My c# code to receive image
[WebMethod]
public byte[] testuploadimage(string image)
{
byte[] imageBytes;
System.Net.HttpWebRequest httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("http://myServer/HeritageWebServices/Service.asmx/testuploadimage");
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/octet-stream";
httpWebRequest.ContentLength = image.Length;
XmlDocument login = new XmlDocument();
XmlDeclaration dec = login.CreateXmlDeclaration("1.0", null, null);
login.AppendChild(dec);
XmlElement root = login.CreateElement("CreateUser");
login.AppendChild(root);
//try
//{
string actFolder = Server.MapPath("~/Images/");
string s = image.Replace(" ", string.Empty);
ErrLogMgr.LogErrorMessage(string.Format("{0}{1}", "testuploadimage() for the image :",
image), "testUploadimage Inputs",
ERRORSOURCE.CSASERVICE);
string imgname = DateTime.UtcNow.ToString().Replace(" ", "").Replace("AM", "").Replace("PM", "").Replace("/", "").Replace("-", "").Replace(":", "") + ".png";
// string imgname = DateTime.UtcNow.ToString("yyyyMMddHHmm") + ".png";
// byte[] imageBytes = Convert.FromBase64String(image.Replace(" ","+"));
imageBytes = HexStringToByteArray(s);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// MemoryStream ms = new MemoryStream(imageBytes);
// Convert byte[] to Image
// ms.Write(imageBytes, 0, imageBytes.Length);
ErrLogMgr.LogErrorMessage(string.Format("{0}{1}", "testuploadimage() for the image :",
image), "testUploadimage Inputs",
ERRORSOURCE.CSASERVICE);
Image image2 = Image.FromStream(ms);
ErrLogMgr.LogErrorMessage(string.Format("{0}{1}", "testuploadimage() for the image :",
image), "testUploadimage Inputs",
ERRORSOURCE.CSASERVICE);
// System.Drawing.Bitmap image2 = new System.Drawing.Bitmap(ms);
image2.Save(actFolder + imgname);
XmlElement root1 = login.CreateElement("uploaded");
root1.InnerText = "true";
root.AppendChild(root1);
XmlElement root2 = login.CreateElement("path");
root2.InnerText = "http://myServer/HeritageWebServices/Images/" + imgname;
root.AppendChild(root2);
// return login;
return imageBytes;
// }
//catch (Exception ex)
//{
// ErrLogMgr.LogErrorMessage(string.Format("{0}{1}", "testuploadimage() for the image :",
// image), "testUploadimage Inputs",
// ERRORSOURCE.CSASERVICE);
// XmlDocument cd = new XmlDocument();
// cd.LoadXml("<Message>" + ex + "</Message>");
// // return cd;
// return imageBytes;
//}
}
private byte[] HexStringToByteArray(string hexString)
{
int bytesCount = (hexString.Length) / 2;
byte[] bytes = new byte[bytesCount];
for (int x = 0; x < bytesCount; ++x)
{
bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16);
}
return bytes;
}
}
For the large image exception which i am getting on server is
System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+. at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) at System.Drawing.Image.Save(String filename, ImageFormat format) at System.Drawing.Image.Save(String filename) at Heritage.Service.testuploadimage(String image) –
Can anybody help me.. What am i doing wrong
Is the problem with my iPhone code of with my c# code.
Thanx!!!
0x80004005 translates to access denied. So, it looks like it's server side config.
Look at the permissions on the path you are trying to save the image as. Also ensure the appPool identity or the end user has write permissions (depends on your asp.net security configuration/delegation settings).

C# Rotating JPG without losing too much quality

So I'm reading in files from a directory, figuring out which way they need to be rotated. Rotating and then saving. That part works... The issue is, after it saves the file it gets recompressed and I go from 1.5meg images to 250k images. I need to keep the file size around the original. I tried using jhead.exe and calling it from a command line but couldn't get any of my arguments to pass in correctly. Here's my code snipit to detect, rotate, and save.
foreach (FileInfo f in dir.GetFiles("*.jpg"))
{
try
{
string ExportName = "";
Bitmap originalImage = new Bitmap(f.FullName.ToString());
Info inf = new Info(originalImage);
gma.Drawing.ImageInfo.Orientation orientation = gma.Drawing.ImageInfo.Orientation.TopLeft;
try
{
orientation = inf.Orientation;
}
catch
{
orientation = gma.Drawing.ImageInfo.Orientation.TopLeft;
}
originalImage = CheckRotation(originalImage, orientation);
progressBar.Value = progressBar.Value + 1;
originalImage.Save(f.FullName.ToString(), ImageFormat.Jpeg);
Application.DoEvents();
}
private Bitmap CheckRotation(Bitmap inputImage, gma.Drawing.ImageInfo.Orientation orientation)
{
Bitmap rotatedImage = inputImage;
switch (orientation)
{
case gma.Drawing.ImageInfo.Orientation.LeftBottom:
rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipXY);
break;
case gma.Drawing.ImageInfo.Orientation.RightTop:
rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
break;
default:
break;
}
return rotatedImage;
}
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = null;
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType == "image/jpeg")
ici = codec;
}
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);
originalImage.Save(f.FullName.ToString(), ici, ep);
This will use 100% quality - but beware, jpegs are still lossy compression - try using a png if you need loss-less quality.
The key for lossless jpeg edit is to use always same QualityLevel and BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile with BitmapCacheOption.None.
And be aware that even if you use QualityLevel 100, quality will go down. With this method goes down just first time, because it goes from unknown QualityLevel to 80, but every other jpeg edit is lossless.
RotateJpeg(#"d:\!test\TestInTest\20160209_143609.jpg", 80, Rotation.Rotate90);
public bool RotateJpeg(string filePath, int quality, Rotation rotation) {
var original = new FileInfo(filePath);
if (!original.Exists) return false;
var temp = new FileInfo(original.FullName.Replace(".", "_temp."));
const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;
try {
using (Stream originalFileStream = File.Open(original.FullName, FileMode.Open, FileAccess.Read)) {
JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = quality, Rotation = rotation};
//BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile and BitmapCacheOption.None
//is a KEY to lossless jpeg edit if the QualityLevel is the same
encoder.Frames.Add(BitmapFrame.Create(originalFileStream, createOptions, BitmapCacheOption.None));
using (Stream newFileStream = File.Open(temp.FullName, FileMode.Create, FileAccess.ReadWrite)) {
encoder.Save(newFileStream);
}
}
}
catch (Exception) {
return false;
}
try {
temp.CreationTime = original.CreationTime;
original.Delete();
temp.MoveTo(original.FullName);
}
catch (Exception) {
return false;
}
return true;
}
Easy...
public static void Rotate90(string fileName)
{
Image Pic;
string FileNameTemp;
Encoder Enc = Encoder.Transformation;
EncoderParameters EncParms = new EncoderParameters(1);
EncoderParameter EncParm;
ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg");
// load the image to change
Pic = Image.FromFile(fileName);
// we cannot store in the same image, so use a temporary image instead
FileNameTemp = fileName + ".temp";
// for rewriting without recompression we must rotate the image 90 degrees
EncParm = new EncoderParameter(Enc,(long)EncoderValue.TransformRotate90);
EncParms.Param[0] = EncParm;
// now write the rotated image with new description
Pic.Save(FileNameTemp,CodecInfo,EncParms);
Pic.Dispose();
Pic = null;
// delete the original file, will be replaced later
System.IO.File.Delete(fileName);
System.IO.File.Move(FileNameTemp, fileName);
}
See reference at:
https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-transforming-a-jpeg-image-without-loss-of-information-use

Categories