上传iPad Air拍摄的JPG图片时出现GDI+通用错误求助
Hey there, let's work through this frustrating GDI+ error you're hitting only with iPad Air photos. I’ve gone over your code and spotted a few key issues that are likely causing the problem, plus straightforward fixes to resolve them:
Common Culprits & Solutions
1. Reusing a Stream That’s Already Been Read
When you create a Bitmap from pic.InputStream, you’re reading the entire stream to its end. Then when you call pic.SaveAs(tmpFilePath), the stream’s pointer is already at the finish line—there’s nothing left to save. This leads to corrupted or empty files, which triggers GDI+ generic errors.
Fix: Copy the uploaded stream to a MemoryStream first, so you can reset and re-read it as needed:
var pic = System.Web.HttpContext.Current.Request.Files[0]; // Copy stream to MemoryStream for reusability MemoryStream ms = new MemoryStream(); pic.InputStream.CopyTo(ms); // Reset pointer to start before creating Bitmap ms.Position = 0; using (Bitmap bmp = new Bitmap(ms)) { DateTime dtaken; PropertyItem propItem; try { propItem = bmp.GetPropertyItem(36867); string sdate = System.Text.Encoding.ASCII.GetString(propItem.Value).Trim('\0'); // Handle null terminators if (DateTime.TryParseExact(sdate, "yyyy:MM:dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dtaken)) { // Parsed successfully } else { dtaken = DateTime.Now; } } catch { dtaken = DateTime.Now; } // Generate file paths 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; // Reset stream again before saving original file ms.Position = 0; using (FileStream fs = new FileStream(tmpFilePath, FileMode.Create)) { ms.CopyTo(fs); } // Resize and save processed image using (var img = FileUtilities.ResizePhoto(newFilePath, newFileName, 800, 600)) { // Handle CMYK to RGB conversion if needed if (img.PixelFormat == PixelFormat.Format32bppCmyk) { using (Bitmap rgbImg = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb)) { using (Graphics g = Graphics.FromImage(rgbImg)) { g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height)); } SaveJpegWithQuality(rgbImg, Path.Combine(newFilePath, newFileName), 100); } } else { SaveJpegWithQuality(img, Path.Combine(newFilePath, newFileName), 100); } } } // Helper method to avoid code duplication private void SaveJpegWithQuality(Image img, string path, long quality) { ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg); Encoder myEncoder = Encoder.Quality; using (EncoderParameters myEncoderParameters = new EncoderParameters(1)) { EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality); myEncoderParameters.Param[0] = myEncoderParameter; img.Save(path, jpgEncoder, myEncoderParameters); } }
2. CMYK Color Profile Compatibility
Some iPad Air photos might be saved in CMYK color mode instead of the more widely supported RGB. GDI+ has limited support for CMYK JPEGs, and trying to save these directly will throw generic errors.
Fix: Add a check to convert CMYK bitmaps to RGB before saving (included in the code above).
3. Unmanaged Resource Leaks
Your original code doesn’t use using statements for Bitmap and Image objects. These hold unmanaged GDI+ resources, and failing to dispose them properly can cause conflicts when writing files to disk.
Fix: Wrap all Bitmap, Image, and stream instances in using blocks to ensure resources are released immediately after use (also included in the code above).
Final Notes
Start with fixing the stream reusability and CMYK conversion—these are the most likely causes of your specific issue with iPad Air photos. The robust EXIF parsing and resource cleanup will help prevent other hidden failures too.
内容的提问来源于stack exchange,提问作者Javi

