เกิดข้อผิดพลาดทั่วไปใน GDI +, JPEG Image to MemoryStream


326

ดูเหมือนว่าจะเป็นข้อผิดพลาดที่น่าอับอายทั่วทั้งเว็บ มากจนฉันไม่สามารถหาคำตอบสำหรับปัญหาของฉันได้เนื่องจากสถานการณ์ของฉันไม่เหมาะสม มีข้อผิดพลาดเกิดขึ้นเมื่อฉันบันทึกรูปภาพไปยังสตรีม

ข้อผิดพลาดนี้ทำงานได้อย่างสมบูรณ์แบบด้วย png แต่ให้ข้อผิดพลาดด้านบนกับ jpg และ gif ซึ่งค่อนข้างสับสน

ปัญหาที่คล้ายกันส่วนใหญ่เกี่ยวข้องกับการบันทึกภาพไปยังไฟล์โดยไม่ได้รับอนุญาต แดกดันวิธีแก้ปัญหาคือการใช้สตรีมหน่วยความจำขณะที่ฉันทำ ....

public static byte[] ConvertImageToByteArray(Image imageToConvert)
{
    using (var ms = new MemoryStream())
    {
        ImageFormat format;
        switch (imageToConvert.MimeType())
        {
            case "image/png":
                format = ImageFormat.Png;
                break;
            case "image/gif":
                format = ImageFormat.Gif;
                break;
            default:
                format = ImageFormat.Jpeg;
                break;
        }

        imageToConvert.Save(ms, format);
        return ms.ToArray();
    }
}

รายละเอียดเพิ่มเติมเกี่ยวกับข้อยกเว้น เหตุผลที่ทำให้เกิดปัญหามากมายคือการขาดคำอธิบาย :(

System.Runtime.InteropServices.ExternalException was unhandled by user code
Message="A generic error occurred in GDI+."
Source="System.Drawing"
ErrorCode=-2147467259
StackTrace:
   at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters    encoderParams)
   at System.Drawing.Image.Save(Stream stream, ImageFormat format)
   at Caldoo.Infrastructure.PhotoEditor.ConvertImageToByteArray(Image imageToConvert) in C:\Users\Ian\SVN\Caldoo\Caldoo.Coordinator\PhotoEditor.cs:line 139
   at Caldoo.Web.Controllers.PictureController.Croppable() in C:\Users\Ian\SVN\Caldoo\Caldoo.Web\Controllers\PictureController.cs:line 132
   at lambda_method(ExecutionScope , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
 InnerException: 

ตกลงสิ่งที่ฉันได้ลองมาแล้ว

  1. การโคลนภาพและการทำเช่นนั้น
  2. การดึงตัวเข้ารหัสสำหรับ MIME นั้นผ่านไปด้วยการตั้งค่าคุณภาพ jpeg



3
สำหรับฉันปัญหาคือโฟลเดอร์นั้นไม่มีอยู่ แก้ไขโดยเพียงแค่สร้างโฟลเดอร์
hazjack

สำหรับฉันมันเป็นดัชนีออกจากช่วงที่กลืนกิน
Billy Jake O'Connor

คำตอบ:


189

ตกลงฉันดูเหมือนจะได้พบสาเหตุโดยโชคดีและไม่มีอะไรผิดปกติกับวิธีการนั้นมันสำรองเพิ่มเติมสแต็คโทร

ก่อนหน้านี้ฉันปรับขนาดรูปภาพและเป็นส่วนหนึ่งของวิธีการนั้นฉันจะคืนค่าวัตถุที่ปรับขนาดดังนี้ ฉันได้แทรกสองสายไปยังวิธีการข้างต้นและบันทึกโดยตรงไปยังไฟล์

// At this point the new bitmap has no MimeType
// Need to output to memory stream
using (var m = new MemoryStream())
{
       dst.Save(m, format);

       var img = Image.FromStream(m);

       //TEST
       img.Save("C:\\test.jpg");
       var bytes = PhotoEditor.ConvertImageToByteArray(img);


       return img;
 }

ปรากฏว่ากระแสหน่วยความจำที่วัตถุที่ถูกสร้างขึ้นบนมีที่จะเปิดในเวลาที่วัตถุที่ถูกบันทึกไว้ ฉันไม่แน่ใจว่าทำไมถึงเป็นเช่นนี้ ทุกคนสามารถให้ความกระจ่างแก่ฉันและฉันจะหลีกเลี่ยงสิ่งนี้ได้อย่างไร

ฉันกลับมาจากกระแสเพราะหลังจากใช้รหัสปรับขนาดคล้ายกับนี้แฟ้มปลายทางมีชนิด MIME ที่ไม่รู้จัก (img.RawFormat.Guid) และ Id เช่นชนิดของไฟล์ที่ถูกต้องบนวัตถุภาพทั้งหมดเป็นก็จะทำให้มันยากที่เขียนทั่วไป การจัดการรหัสมิฉะนั้น

แก้ไข

นี่ไม่ได้เกิดขึ้นในการค้นหาครั้งแรกของฉัน แต่นี่คือคำตอบจาก Jon Skeet


4
ฉันไม่ทราบว่าเมื่อคุณได้รับบิตแมปจากหน่วยความจำคุณไม่ควรปิดสตรีม มีประโยชน์มากขอบคุณ
mcdon

38
ขอบคุณ. นี่อาจช่วยผมสุดท้ายของฉัน
NotMe

6
ขอบคุณ! สิ่งนี้ช่วยให้ฉันประหยัดเวลาได้มากสิ่งหนึ่งที่คุณคิดจะเน้นสาเหตุของข้อผิดพลาดที่จุดเริ่มต้นของคำตอบของคุณในขณะที่ฉัน (และฉันเดาว่าคนส่วนใหญ่) พลาดมันไปบน skim ดั้งเดิมผ่านคำตอบ อย่าปิดสตรีมหน่วยความจำหากคุณตั้งใจที่จะใช้ภาพอีกครั้ง "จะดีมาก D
DorD

6
ตัวแปร "dst" ของคุณคืออะไร
WEFX

1
@madcapnmckay โปรดอธิบายว่าตัวแปร 'dst' คืออะไรและมีความสำคัญอย่างไร
Mike T

131

หากคุณได้รับข้อผิดพลาดฉันสามารถบอกได้ว่าแอปพลิเคชันของคุณไม่มีสิทธิ์ในการเขียนในบางไดเรกทอรี

ตัวอย่างเช่นหากคุณพยายามบันทึกภาพจากกระแสหน่วยความจำไปยังระบบไฟล์คุณอาจได้รับข้อผิดพลาดนั้น

กรุณาถ้าคุณใช้ XP ตรวจสอบให้แน่ใจว่าได้เพิ่มสิทธิ์ในการเขียนสำหรับบัญชี aspnet ในโฟลเดอร์นั้น

หากคุณใช้ windows server (2003,2008) หรือ Vista ตรวจสอบให้แน่ใจว่าเพิ่มสิทธิ์การเขียนสำหรับบัญชีบริการเครือข่าย

หวังว่ามันจะช่วยได้บ้าง


7
คุณไม่ได้! ฉันเสียเวลา 2 ชั่วโมงกับการเขียนเพื่อขออนุญาต ... มาที่นี่เพื่อโพสต์สิ่งนี้ หวังว่าคุณจะได้รับ upvotes มากขึ้น :)
Gleno

2
นี่คือทางออกสำหรับฉัน +1 ทั้งหมด!
Grandizer

5
คุณสามารถทำ File.WriteAllText ("filename.jpg", "") แล้วตามด้วย File.DeleteFile ("filename.jpg") ก่อนที่คุณจะบันทึกบิตแมป ใน benmark ของฉันนี้ใช้เวลาเพียง 0.001 วินาทีและคุณจะได้รับ 'คุณไม่ได้รับอนุญาตให้บันทึก filename.jpg ที่นั่น'
Despertar

@Despertar คุณหมายถึง File.Delete () แต่นั่นเป็นเคล็ดลับที่มีประโยชน์มาก! จะใช้มันอย่างแน่นอนทุกครั้งที่ฉันบันทึกบิตแมป
D Coetzee

2
ในกรณีของฉันไม่มีไดเรกทอรีอยู่
เงียบ

54

ฉันจะเพิ่มสาเหตุของข้อผิดพลาดนี้และหวังว่าจะช่วยนักเดินทางทางอินเทอร์เน็ตในอนาคต :)

GDI + จำกัดความสูงสูงสุดของภาพไว้ที่ 65500

เราทำการปรับขนาดรูปภาพพื้นฐานบางส่วน แต่ในการปรับขนาดเราพยายามรักษาอัตราส่วนภาพ เรามีผู้ชาย QA ที่เก่งในงานนี้เล็กน้อย เขาตัดสินใจทดสอบด้วยภาพกว้างหนึ่งพิกเซลที่สูง 480 พิกเซล เมื่อภาพถูกปรับขนาดให้ตรงกับขนาดของเราความสูงนั้นอยู่ทางเหนือของ 68,000 พิกเซลและแอปของเราก็ระเบิดออกA generic error occurred in GDI+มา

คุณสามารถยืนยันตัวเองด้วยการทดสอบ:

  int width = 480;
  var height = UInt16.MaxValue - 36; //succeeds at 65499, 65500
  try
  {
    while(true)
    {
      var image = new Bitmap(width, height);
      using(MemoryStream ms = new MemoryStream())
      {
        //error will throw from here
        image.Save(ms, ImageFormat.Jpeg);
      }
      height += 1;
    }
  }
  catch(Exception ex)
  {
    //explodes at 65501 with "A generic error occurred in GDI+."
  }

มันเลวร้ายเกินไปมีไม่ .net มิตรโยนในตัวสร้างของArgumentExceptionBitmap


17
ขอบคุณ - นักท่องกาลเวลาบนอินเทอร์เน็ตนี้รู้สึกขอบคุณเป็นอย่างยิ่งที่ได้ฝากข้อความนี้ไว้
Tom West

จากการทดสอบของฉัน 65535 เป็นมูลค่าสูงสุดจริง ๆ ที่ 65536 ฉันเริ่มเห็นข้อผิดพลาดทั่วไป
ChaseMedallion

ลองใหม่อีกครั้ง: Win10 .net 4.5 และ. net 4.6.1 และมันระเบิดที่ 65501 ซึ่งดูเหมือนจะสุ่มมากขึ้น รหัสนอกจากนี้ยังเต็มไปด้วยข้อผิดพลาดไวยากรณ์จะปรับปรุง :)
เฟร็ด

37

บทความนี้อธิบายในรายละเอียดว่าเกิดอะไรขึ้น: การพึ่งพาบิตแมปและตัวสร้างรูปภาพ

กล่าวโดยย่อว่าตลอดชีวิตของการImageสร้างจากสตรีมสตรีมจะต้องไม่ถูกทำลาย

ดังนั้นแทนที่จะ

using (var strm = new ... )  {
    myImage = Image.FromStream(strm);
}

ลองนี้

Stream imageStream;
...

    imageStream = new ...;
    myImage = Image.FromStream(strm);

และปิดimageStreamที่แบบฟอร์มปิดหรือปิดหน้าเว็บ


ใช่หนึ่งนี้ได้ฉัน ฉันถูกมโนธรรมและห่อกระแสข้อมูลของฉันในusingและหลังจากนั้นพยายามที่จะคัดลอกภาพลงในหน่วยความจำและได้รับข้อความ "ข้อผิดพลาดทั่วไปใน GDI +" ที่น่ากลัว
จะ Appleby

ลิงก์ของคุณให้การเปลี่ยนเส้นทางแบบไม่ จำกัด แก่ฉัน อันนี้ใช้ได้ผล ผมได้รับมีปัญหากับการประหยัดแต่ไม่PixelFormat.Format32bppArgb PixelFormat.Format1bppIndexedบทความที่คุณเชื่อมโยงอธิบายถึงสาเหตุ: GDI + อาจเลือกที่จะถอดรหัสบิตแมปข้อมูลใหม่จากสตรีมต้นทางแทนที่จะเก็บทุกอย่างไว้ในหน่วยความจำ ฉันเดาว่ามันไม่ได้ถอดรหัสภาพ 1bpp อีกครั้ง
labreuer

แม้แต่ลิงค์ใหม่ก็ใช้ไม่ได้อีกต่อไป การค้นหา google อย่างง่ายดูเหมือนจะไม่เปิดเผยหน้าที่ถูกต้อง แต่ฉันดีใจมากที่พบคำตอบนี้! การทำงานของฉันโดยการคัดลอกไปยังบิตแมปใหม่ล้มเหลวเนื่องจากปัญหานี้
Katjoek

28

นอกจากนี้คุณยังจะได้รับข้อยกเว้นนี้หากคุณพยายามบันทึกไปยังเส้นทางที่ไม่ถูกต้องหรือหากมีปัญหาการอนุญาต

หากคุณไม่แน่ใจ 100% ว่าเส้นทางของไฟล์นั้นพร้อมใช้งานและการอนุญาตถูกต้องให้ลองเขียน a ไปยังไฟล์ข้อความ ใช้เวลาเพียงไม่กี่วินาทีในการแยกแยะว่าอะไรคือการแก้ไขที่ง่ายมาก

var img = System.Drawing.Image.FromStream(incomingStream);

// img.Save(path);
System.IO.File.WriteAllText(path, "Testing valid path & permissions.");

และอย่าลืมล้างไฟล์ของคุณ


นี่เป็นปัญหาสำหรับฉัน ... ฉันหวังว่าข้อผิดพลาดจะคลุมเครือน้อยลงจะช่วยฉันได้มาก
Oofpez

ใช่ โฟลเดอร์ที่คุณกำลังบันทึกไว้จะต้องมีอยู่ ตอนนี้ฉันจะตรวจสอบก่อนว่าก่อนที่ฉันจะพยายามบันทึกภาพ (ถึงกระนั้นข้อผิดพลาดก็ดึงฉันออกมาประมาณปีละครั้ง)
แมกนัสสมิ ธ

เส้นทางของฉันเป็นไดเรกทอรีแทนที่จะเป็นไฟล์
Asen Kasimov

20

บันทึกภาพเป็นตัวแปรบิตแมป

using (var ms = new MemoryStream())
{
    Bitmap bmp = new Bitmap(imageToConvert);
    bmp.Save(ms, format);
    return ms.ToArray();
}

นี่เป็นการแก้ไขปัญหาของฉัน คุณช่วยอธิบายได้ไหมว่าทำไมการบันทึกภาพไปยังบิตแมปทำให้เกิดข้อยกเว้นขึ้นมา?
jmc

บันทึกวันของฉัน .. ไม่ทราบว่าเกิดอะไรขึ้น แต่บันทึกบิตแมปทำงาน .. System.Drawing.Image จะไม่บันทึกลงในหน่วยความจำกระแส แต่บิตแมปไม่ !!!
San

นี่เป็นทางออกที่ดีที่สุดสำหรับฉัน สร้างบิตแมปใหม่และแปลงจากมัน
uzay95

17

ในกรณีที่มีคนทำอะไรโง่ ๆ เหมือนฉัน 1. ตรวจสอบให้แน่ใจว่ามีเส้นทางอยู่ 2. ตรวจสอบให้แน่ใจว่าคุณมีสิทธิ์ในการเขียน 3. ตรวจสอบให้แน่ใจว่าเส้นทางของคุณถูกต้องในกรณีของฉันฉันไม่มีชื่อไฟล์ใน TargetPath :(

มันควรจะกล่าวว่าเส้นทางของคุณแย่กว่า "มีข้อผิดพลาดทั่วไปเกิดขึ้นใน GDI +"


16

ฉันยังได้รับข้อผิดพลาดนี้เมื่อบันทึก JPEG แต่สำหรับบางภาพเท่านั้น

รหัสสุดท้ายของฉัน:

  try
  {
    img.SaveJpeg(tmpFile, quality); // This is always successful for say image1.jpg, but always throws the GDI+ exception for image2.jpg
  }
  catch (Exception ex)
  {
    // Try HU's method: Convert it to a Bitmap first
    img = new Bitmap(img); 
    img.SaveJpeg(tmpFile, quality); // This is always successful
  }

ฉันไม่ได้สร้างภาพดังนั้นฉันจึงไม่สามารถบอกได้ว่าความแตกต่างคืออะไร
ฉันยินดีถ้าใครสามารถอธิบายได้

นี่คือฟังก์ชัน SaveJpeg ของฉันเพียงแค่ FYI:

private static void SaveJpeg(this Image img, string filename, int quality)
{
  EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, (long)quality);
  ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
  EncoderParameters encoderParams = new EncoderParameters(1);
  encoderParams.Param[0] = qualityParam;
  img.Save(filename, jpegCodec, encoderParams);
}

private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
    var encoders = ImageCodecInfo.GetImageEncoders();
    var encoder = encoders.SingleOrDefault(c => string.Equals(c.MimeType, mimeType, StringComparison.InvariantCultureIgnoreCase));
    if (encoder == null) throw new Exception($"Encoder not found for mime type {mimeType}");
    return encoder;
}

1
วันนี้ได้รับการแก้ไขของการดึงผม มันเป็นรหัส WTF ที่สุดผมคิดว่าผมเคยเขียน :)
เจฟฟ์ Dunlop

13

ฉันพบว่าหากหนึ่งในโฟลเดอร์พาเรนต์ที่ฉันบันทึกไฟล์นั้นมีพื้นที่ต่อท้าย GDI + จะทำให้เกิดข้อยกเว้นทั่วไป

กล่าวอีกนัยหนึ่งถ้าฉันพยายามบันทึกเป็น "C: \ Documents และ Settings \ myusername \ Local Settings \ Temp \ ABC DEF M1 ค่านิยมที่มีแนวโน้ม \ Images \ picture.png" แล้วมันก็โยนข้อยกเว้นทั่วไป

ชื่อโฟลเดอร์ของฉันถูกสร้างขึ้นจากชื่อไฟล์ที่เกิดขึ้นมีพื้นที่ต่อท้ายดังนั้นจึงง่ายต่อการ. TRIM () และย้ายไป


3
ยอดเยี่ยม - ฉันจะไม่เคยคิดที่จะดูเส้นทางไดเรกทอรีที่ใกล้ชิด
jharr100

11

หากรหัสของคุณดังต่อไปนี้ข้อผิดพลาดนี้จะเกิดขึ้นด้วย

private Image GetImage(byte[] byteArray)
{
   using (var stream = new MemoryStream(byteArray))
   {
       return Image.FromStream(stream);
    }
}

สิ่งที่ถูกต้องคือ

private Image GetImage(byte[] byteArray)
{
   var stream = new MemoryStream(byteArray))
   return Image.FromStream(stream);        
}

อาจเป็นเพราะเรากลับมาจากการใช้บล็อก


สำหรับฉันมันคือการกลับมาในการใช้บล็อก ฉันยังคงใช้อยู่ แต่ฉันคืนค่าภายนอกบล็อก ขอบคุณ!
Dragouf

1
ฉันพบ "วิธีที่ยาก" ที่ถ้าคุณบันทึกอีกครั้งว่า Image ไปที่สตรีมใหม่ (เช่น HttpContext.Response.OutputStream เป็นต้น) คุณจะต้องทำการสตรีม Flush () หากไม่ใช่ข้อผิดพลาดเกิดขึ้น อีกครั้ง
ลูเชีย

11

นี่คือส่วนขยาย / คุณสมบัติของการตอบกลับของ Fred ซึ่งระบุไว้ว่า: "GDI จำกัดความสูงของภาพไว้ที่ 65534" เราพบปัญหานี้กับหนึ่งในแอปพลิเคชั่น. NET ของเราและเมื่อเห็นโพสต์นั้นทีมงานเอาท์ซอร์สของเราก็ยกมือขึ้นกลางอากาศและบอกว่าพวกเขาไม่สามารถแก้ไขปัญหาได้หากไม่มีการเปลี่ยนแปลงครั้งใหญ่

จากการทดสอบของฉันเป็นไปได้ที่จะสร้าง / จัดการภาพที่มีความสูงมากกว่า 65534 แต่ปัญหาเกิดขึ้นเมื่อบันทึกลงในสตรีมหรือไฟล์ในรูปแบบที่แน่นอน ในรหัสต่อไปนี้การเรียกใช้เมธอด t.Save () ทำให้เพื่อนของเรามีข้อยกเว้นทั่วไปเมื่อความสูงพิกเซลเป็น 65501 สำหรับฉัน ด้วยเหตุผลของความอยากรู้ฉันทำการทดสอบความกว้างซ้ำและใช้ข้อ จำกัด เดียวกันกับการบันทึก

    for (int i = 65498; i <= 100000; i++)
    {
        using (Bitmap t = new Bitmap(800, i))
        using (Graphics gBmp = Graphics.FromImage(t))
        {
            Color green = Color.FromArgb(0x40, 0, 0xff, 0);
            using (Brush greenBrush = new SolidBrush(green))
            {
                // draw a green rectangle to the bitmap in memory
                gBmp.FillRectangle(greenBrush, 0, 0, 799, i);
                if (File.Exists("c:\\temp\\i.jpg"))
                {
                    File.Delete("c:\\temp\\i.jpg");
                }
                t.Save("c:\\temp\\i.jpg", ImageFormat.Jpeg);
            }
        }
        GC.Collect();
    }

ข้อผิดพลาดเดียวกันนี้ยังเกิดขึ้นถ้าคุณเขียนไปยังกระแสหน่วยความจำ

ในการปัดเศษคุณสามารถทำซ้ำรหัสข้างต้นและแทนที่ ImageFormat.Tiff หรือ ImageFormat.Bmp สำหรับ ImageFormat.Jpeg

สิ่งนี้มีความสูง / ความกว้าง 100,000 สำหรับฉัน - ฉันไม่ได้ทดสอบขีด จำกัด ในขณะที่มันเกิดขึ้น Tiff เป็นตัวเลือกที่ทำงานได้สำหรับเรา

ได้รับการเตือน

การสตรีม / ไฟล์ TIFF ในหน่วยความจำใช้หน่วยความจำมากกว่าคู่ JPG ของพวกเขา


10

มีปัญหาที่คล้ายกันมากและพยายามโคลนภาพที่ใช้งานไม่ได้ ฉันพบว่าทางออกที่ดีที่สุดคือการสร้างวัตถุบิตแมปใหม่จากภาพที่โหลดจากสตรีมหน่วยความจำ ด้วยวิธีนี้สตรีมสามารถกำจัดได้เช่น

using (var m = new MemoryStream())
{
    var img = new Bitmap(Image.FromStream(m));
    return img;
}

หวังว่านี่จะช่วยได้


6

เกิดข้อผิดพลาดเนื่องจากได้รับอนุญาต ตรวจสอบให้แน่ใจว่าโฟลเดอร์มีสิทธิ์ทั้งหมด

public Image Base64ToImage(string base64String)
    {
        // Convert Base64 String to byte[]
        byte[] imageBytes = Convert.FromBase64String(base64String);
        MemoryStream ms = new MemoryStream(imageBytes, 0,
          imageBytes.Length);

        // Convert byte[] to Image
        ms.Write(imageBytes, 0, imageBytes.Length);
        Image image = Image.FromStream(ms, true);
        return image;
    }

 img.Save("YOUR PATH TO SAVE IMAGE")

ฉันเห็นด้วยกับคุณ. ฉันแก้ไขปัญหานี้ด้วยสิทธิ์
praguan

5

แก้ไขแล้ว - ฉันมีปัญหาตรงนี้ การแก้ไขสำหรับฉันคือเพิ่มโควต้าดิสก์สำหรับ IUSR บนเซิร์ฟเวอร์ IIS ในตัวอย่างนี้เรามีแอพแคตตาล็อกพร้อมรูปภาพรายการและอื่น ๆ โควต้าการอัปโหลดสำหรับ "ผู้ใช้เว็บที่ไม่ระบุชื่อ" ถูกกำหนดเป็น 100MB ซึ่งเป็นค่าเริ่มต้นสำหรับเซิร์ฟเวอร์ IIS ของ บริษัท โฮสต์นี้ ฉันอัปเกรดเป็น 400MB และสามารถอัปโหลดภาพได้โดยไม่มีข้อผิดพลาด

นี่อาจไม่ใช่ปัญหาของคุณ แต่ถ้าเป็นมันเป็นการแก้ไขที่ง่าย


4

ในกรณีของฉันปัญหาเกิดขึ้นในเส้นทางที่ฉันบันทึก (รูทC:\) เปลี่ยนเป็นD:\111\ทำให้ข้อยกเว้นหายไป


4

สาเหตุอื่นสำหรับข้อผิดพลาดนี้ - เส้นทางที่คุณระบุในวิธีการบันทึกของอินสแตนซ์บิตแมปไม่มีอยู่หรือคุณไม่ได้ระบุเส้นทางแบบเต็ม / ถูกต้อง

เพิ่งมีข้อผิดพลาดนี้เพราะฉันผ่านชื่อไฟล์ไม่ใช่เส้นทางที่เต็ม!

มันเกิดขึ้น!


4

ตาฉัน!

using (System.Drawing.Image img = Bitmap.FromFile(fileName))
{
      ... do some manipulation of img ...
      img.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}

รับทราบในการบันทึก ... เนื่องจากการใช้ () กำลังเปิดไฟล์ไว้ดังนั้นฉันจึงไม่สามารถเขียนทับได้ บางทีนี่อาจช่วยคนในอนาคต


4

ปัญหาเดียวกันที่ฉันกำลังเผชิญ แต่ในกรณีของฉันฉันพยายามบันทึกไฟล์ในไดรฟ์ C และไม่สามารถเข้าถึงได้ ดังนั้นฉันจึงพยายามที่จะบันทึกในไดรฟ์ D ซึ่งสามารถเข้าถึงได้อย่างสมบูรณ์และฉันก็ทำได้สำเร็จ

ดังนั้นก่อนตรวจสอบโฟลเดอร์ของคุณที่คุณพยายามจะบันทึก คุณต้องมีสิทธิ์ทั้งหมด (อ่านและเขียน) สำหรับโฟลเดอร์นั้น


สาเหตุปกติ c ไม่อนุญาตหากไม่ได้รับอนุญาตจากผู้ดูแลระบบ
Aneeq Azam Khan

2

ฉันสังเกตเห็นว่ากรณี "jpeg" ของคุณเป็นจริง:

            default:
                format = ImageFormat.Jpeg;
                break;

คุณแน่ใจหรือว่ารูปแบบเป็น jpeg และไม่ใช่อย่างอื่น?

ฉันจะลอง:

            case "image/jpg": // or "image/jpeg" !
                format = ImageFormat.Jpeg;
                break;

หรือตรวจสอบสิ่งที่imageToConvert.MimeType()ส่งคืนจริง

UPDATE

มีการเริ่มต้นอื่น ๆ ที่คุณต้องทำกับวัตถุ MemoryStream หรือไม่?


ขอบคุณ มันถูกเรียกอย่างแน่นอนด้วยรูปแบบที่ถูกต้อง ฉันโหลด jpg ตรวจแก้จุดบกพร่องและยืนยันว่า mime ได้รับการยอมรับว่าเป็นรูปภาพ / jpeg และรูปแบบคือ JPG
madcapnmckay

3
โอ้ดี - ฉันพยายามกำจัดสิ่งที่ชัดเจนออกไปก่อนเสมอ ฉันไม่สามารถนับจำนวนครั้งที่ฉันไม่ได้ทำอย่างนั้นได้และมันจะกลับมากัดฉันในภายหลัง
ChrisF

2
  • ฉันมีปัญหานี้ในเซิร์ฟเวอร์ทดสอบ แต่ไม่ได้อยู่ในเซิร์ฟเวอร์สด
  • ฉันกำลังเขียนภาพไปยังสตรีมดังนั้นจึงไม่ใช่ปัญหาสิทธิ์
  • ฉันได้ปรับใช้. dll บางอย่างไปยังเซิร์ฟเวอร์ทดสอบโดยตรง
  • การปรับใช้โซลูชันทั้งหมดแก้ไขปัญหาดังนั้นอาจเป็นข้อผิดพลาดในการรวบรวมแปลก ๆ

2

เพียงโยนสารละลายอื่นที่เป็นไปได้ลงบนเสาเข็มฉันจะพูดถึงกรณีที่ฉันพบกับข้อความแสดงข้อผิดพลาดนี้ วิธีนี้Bitmap.Saveจะทำให้เกิดข้อยกเว้นนี้เมื่อบันทึกบิตแมปที่ฉันแปลงและแสดง ฉันค้นพบว่ามันจะไม่เกิดข้อยกเว้นหากข้อความมีจุดพักบนมันและจะไม่เกิดขึ้นถ้าสิ่งBitmap.Saveนั้นถูกนำหน้าThread.Sleep(500)ดังนั้นฉันจึงคิดว่ามีการช่วงชิงทรัพยากรบางอย่างเกิดขึ้น

เพียงคัดลอกภาพไปยังวัตถุบิตแมปใหม่ก็เพียงพอที่จะป้องกันข้อยกเว้นนี้ไม่ให้ปรากฏ:

new Bitmap(oldbitmap).Save(filename);

2

เรามีปัญหาที่คล้ายกันในการสร้างPDFหรือปรับขนาดภาพโดยใช้ ImageProcessor lib บนเซิร์ฟเวอร์ที่ใช้งานจริง

รีไซเคิลกลุ่มแอปพลิเคชันแก้ไขปัญหา


1

หากคุณพยายามที่จะบันทึกภาพไปยังสถานที่ห่างไกลให้แน่ใจว่าได้เพิ่มNETWORK_SERVICEบัญชีผู้ใช้ลงในการตั้งค่าความปลอดภัยและให้สิทธิ์ผู้ใช้ในการอ่านและเขียน ไม่อย่างนั้นมันจะไม่ทำงาน


1
byte[] bts = (byte[])page1.EnhMetaFileBits; 
using (var ms = new MemoryStream(bts)) 
{ 
    var image = System.Drawing.Image.FromStream(ms); 
    System.Drawing.Image img = image.GetThumbnailImage(200, 260, null, IntPtr.Zero);      
    img.Save(NewPath, System.Drawing.Imaging.ImageFormat.Png);
}

1

ฉันยังได้รับข้อผิดพลาดนี้เพราะฉันพยายามบันทึกภาพด้วยชื่อเดิมของภาพที่บันทึกไว้ก่อนหน้านี้

ตรวจสอบให้แน่ใจว่าคุณไม่ได้บันทึกภาพด้วยชื่อซ้ำ

ใช้สำหรับ thar เช่นฟังก์ชั่น 'Random' ( เครื่องสร้างตัวเลขสุ่มของ C # ทำงานอย่างไร ) หรือตัวอย่างเช่นสร้าง Guid ( http://betterexplained.com/articles/the-quick-guide-to-guids/ )



0

สำหรับฉันฉันใช้Image.Save(Stream, ImageCodecInfo, EncoderParameters)และเห็นได้ชัดว่านี่เป็นสาเหตุของA generic error occurred in GDI+ข้อผิดพลาดที่น่าอับอาย

ฉันพยายามใช้EncoderParameterเพื่อบันทึก jpegs ในคุณภาพ 100% นี่ทำงานได้อย่างสมบูรณ์ใน "เครื่องของฉัน" (doh!) และไม่ได้ใช้งานจริง

เมื่อฉันใช้Image.Save(Stream, ImageFormat)แทนข้อผิดพลาดหายไป! เช่นเดียวกับคนงี่เง่าฉันยังคงใช้ตัวหลังอย่างต่อเนื่องแม้ว่ามันจะช่วยพวกเขาในคุณภาพเริ่มต้นซึ่งฉันคิดว่ามันแค่ 50%

หวังว่าข้อมูลนี้จะช่วยให้ใครบางคน


0

ฉันพบปัญหาเช่นกัน ปัญหาเกิดจากการโหลดกระแสที่ถูกกำจัด แต่ฉันไม่ได้กำจัดมันอยู่ในกรอบสุทธิ. สิ่งที่ฉันต้องทำคือใช้:

image_instance = Image.FromFile(file_name);

แทน

image_instance.Load(file_name);

image_instance เป็นชนิด System.Windows รูปแบบรูปภาพ! โหลดของ PictureBox () จะตัดการสตรีมที่โหลดรูปภาพจากและฉันไม่ทราบ


0

ขึ้นอยู่กับคำตอบจาก @savindra หากคุณRHMในใบสมัครของคุณและลองและเรียกใช้ในฐานะผู้ดูแลระบบก็ควรแก้ไขปัญหาของคุณ

ฉันดูเหมือนจะเป็นปัญหาที่ได้รับอนุญาต


0

ปัญหาที่เป็นไปได้ที่ทำให้เกิดข้อผิดพลาดคือ:

  1. ไม่มีไดเรกทอรี (วิธีที่คุณโทรจะไม่สร้างไดเรกทอรีนี้ให้คุณโดยอัตโนมัติ)
  2. สิทธิ์ความปลอดภัยในการเขียนไปยังไดเรกทอรีผลลัพธ์ไม่อนุญาตให้ผู้ใช้ที่เรียกใช้แอปเขียน

ฉันหวังว่านี่จะช่วยได้นี่คือการแก้ไขปัญหาของฉันฉันเพียงแค่ทำให้แน่ใจว่ามีไดเรกทอรีไดเรกทอรีอยู่ก่อนที่จะบันทึกภาพเอาท์พุท!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.