C# Image.Save AccessViolationException -


i have function, builds image pixel array , saves file. works without problems when called once. if call twice (after it's executed first time), function throws accessviolationexception.

private void saveimage(byte[] bmpbytes) {     debug.print("image saving started");      var arrayhandle = system.runtime.interopservices.gchandle.alloc(bmpbytes, system.runtime.interopservices.gchandletype.pinned);     system.drawing.image bmp = new system.drawing.bitmap(960, 540, 960 * 3, pixelformat.format24bpprgb, arrayhandle.addrofpinnedobject());     bmp.save("img.bmp");      debug.print("image saving completed"); } 

so, bmp.save("img.bmp"); line throws exception. i've tried saving data in memorystream, same result: success on first call , accessviolationexception every other time. reason can be?

this error states trying access protected memory. passed array of lesser size image required. it's similar buffer overflow. when gdi tries read memory image, goes beyond what's allocated process memory , failure occurs. way, behavior undefined. example, if piece of memory allocated process read whatever has , receive no error. in case see image noise.

are sure you're passing array of valid length? try add corresponding checks. , not forget free allocated memory - gchandle must released free when no longer needed.

just ran code , got no errors:

int width = 960; int height = 540;  void main() {     var arr = enumerable.range(0, width * height * 3).select(i =>     {         = / 3;         var y = / width;         var x = - y * width;         var xd = x / (double)(width - 1);         var yd = y / (double)(height - 1);         return (byte)((xd + yd) / 2d * 255);     }).toarray();     saveimage2(arr); }  private void saveimage2(byte[] bmpbytes) {     if (bmpbytes == null)         throw new argumentnullexception("bmpbytes");      if (bmpbytes.length != width * height * 3)         throw new argumentexception("invalid array length", "bmpbytes");      var output = new bitmap(width, height, pixelformat.format24bpprgb);     var rect = new rectangle(0, 0, width, height);     var bmpdata = output.lockbits(rect, imagelockmode.writeonly, output.pixelformat);      // stride must taken account.     // actual row length may greater required due gdi's internal memory alignment.     // error copy entire array as-is, need copy row-by-row.     var rowbytes = width * image.getpixelformatsize(output.pixelformat) / 8;     var ptr = bmpdata.scan0;     (var = 0; < height; i++)     {         marshal.copy(bmpbytes, * rowbytes, ptr, rowbytes);         ptr += bmpdata.stride;     }      output.unlockbits(bmpdata);      output.save(@"d:\temp\img.bmp"); } 

Comments

Popular posts from this blog

gridview - Yii2 DataPorivider $totalSum for a column -

java - Suppress Jboss version details from HTTP error response -

Sass watch command compiles .scss files before full sftp upload -