OutOfMemory Exception on saving image

  • Thread starter Thread starter ELandry
  • Start date Start date
E

ELandry

I am trying to convert an image to a bitonal image and am getting am
OutOfMemory exception. Below is the method that I am using. I am passing in
a byte array as an image, attempting to convert it to a B&W bitonal image or
bitmap, then return the byte array of the converted image. Error is occuring
on the line with the "TODO" comment.

private byte[] createBlackAndWhiteImageFromBuffer(byte[] buffer)
{
string tempfilename = Path.Combine(Path.GetTempPath(),
String.Format("{0}.tif", Guid.NewGuid()));

Bitmap image = (Bitmap)Bitmap.FromStream(new
MemoryStream(buffer, 0, buffer.Length));

buffer = null;

GC.Collect();

Guid objGuid = image.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);

System.Drawing.Imaging.Encoder encoder =
System.Drawing.Imaging.Encoder.SaveFlag;

ImageCodecInfo info = GetEncoderInfo("image/tiff");

Bitmap pagebitmap = null;

using (MemoryStream str = new MemoryStream())
{
try
{
EncoderParameters ep = new EncoderParameters(2);

ep.Param[1] = new EncoderParameter(encoder,
(long)EncoderValue.CompressionCCITT4);

for (int i = 0; i < image.GetFrameCount(objDimension);
i++)
{
image.SelectActiveFrame(FrameDimension.Page, i);

if (i == 0)
{
pagebitmap = image.Clone(new Rectangle(0, 0,
image.Width, image.Height), PixelFormat.Format1bppIndexed); //TODO: Out of
Memory exception

ep.Param[0] = new EncoderParameter(encoder,
(long)EncoderValue.MultiFrame);
pagebitmap.Save(tempfilename, info, ep);
}
else
{
using (MemoryStream mstream = new MemoryStream())
{
ep.Param[0] = new EncoderParameter(encoder,
(long)EncoderValue.FrameDimensionPage);
image.Save(mstream, ImageFormat.Bmp);

using (Bitmap tempbmp =
((Bitmap)Bitmap.FromStream(mstream)).Clone(new Rectangle(0, 0, image.Width,
image.Height), PixelFormat.Format1bppIndexed))
{
pagebitmap.SaveAdd(tempbmp, ep);
}
}
}

if (i == (image.GetFrameCount(objDimension) - 1))
{
ep.Param[0] = new EncoderParameter(encoder,
(long)EncoderValue.Flush);
pagebitmap.SaveAdd(ep);
}
}



using (FileStream reader = new FileStream(tempfilename,
FileMode.Open, FileAccess.Read))
{

buffer = new byte[reader.Length];

reader.Read(buffer, 0, (int)reader.Length);

reader.Close();
}
}
finally
{
GC.Collect();

if (pagebitmap != null)
{
pagebitmap.Dispose();
}

if (image != null)
{
image.Dispose();
}

if (File.Exists(tempfilename))
{
File.Delete(tempfilename);
}

GC.Collect();
}
}
return buffer;
}
 
ELandry said:
I am trying to convert an image to a bitonal image and am getting am
OutOfMemory exception. Below is the method that I am using. I am passing in
a byte array as an image, attempting to convert it to a B&W bitonal image or
bitmap, then return the byte array of the converted image. Error is occuring
on the line with the "TODO" comment.

I didn't bother to look at the code closely. It doesn't look like you
have posted the minimal code example required to reproduce the problem,
and in any case without indentation, it's just not worth the
trouble...too hard to read.

But, I can tell you that due to the dependency on GDI+ for image
handling, unfortunately often the error returned is "out of memory" even
when the real problem is something else (usually, for example,
attempting to process an image using a format that's not supported by
GDI+ for that operation).

Pete
 
Publish complete exception information with call stack, because GDI+ classes can throw OutOfMemory exception to many cases

http://www.google.com/search?q=OutO...=t&rls=org.mozilla:ru:official&client=firefox



ELandry wrote:

OutOfMemory Exception on saving image
20-???-09

I am trying to convert an image to a bitonal image and am getting a
OutOfMemory exception. Below is the method that I am using. I am passing i
a byte array as an image, attempting to convert it to a B&W bitonal image o
bitmap, then return the byte array of the converted image. Error is occurin
on the line with the "TODO" comment

private byte[] createBlackAndWhiteImageFromBuffer(byte[] buffer

string tempfilename = Path.Combine(Path.GetTempPath()
String.Format("{0}.tif", Guid.NewGuid()))

Bitmap image = (Bitmap)Bitmap.FromStream(ne
MemoryStream(buffer, 0, buffer.Length))

buffer = null

GC.Collect()

Guid objGuid = image.FrameDimensionsList[0]
FrameDimension objDimension = new FrameDimension(objGuid)

System.Drawing.Imaging.Encoder encoder
System.Drawing.Imaging.Encoder.SaveFlag

ImageCodecInfo info = GetEncoderInfo("image/tiff")

Bitmap pagebitmap = null

using (MemoryStream str = new MemoryStream()

tr

EncoderParameters ep = new EncoderParameters(2)

ep.Param[1] = new EncoderParameter(encoder
(long)EncoderValue.CompressionCCITT4)

for (int i = 0; i < image.GetFrameCount(objDimension)
i++

image.SelectActiveFrame(FrameDimension.Page, i)

if (i == 0

pagebitmap = image.Clone(new Rectangle(0, 0
image.Width, image.Height), PixelFormat.Format1bppIndexed); //TODO: Out o
Memory exceptio

ep.Param[0] = new EncoderParameter(encoder
(long)EncoderValue.MultiFrame)
pagebitmap.Save(tempfilename, info, ep)

els

using (MemoryStream mstream = new MemoryStream()

ep.Param[0] = new EncoderParameter(encoder
(long)EncoderValue.FrameDimensionPage)
image.Save(mstream, ImageFormat.Bmp)

using (Bitmap tempbmp
((Bitmap)Bitmap.FromStream(mstream)).Clone(new Rectangle(0, 0, image.Width
image.Height), PixelFormat.Format1bppIndexed)

pagebitmap.SaveAdd(tempbmp, ep)




if (i == (image.GetFrameCount(objDimension) - 1)

ep.Param[0] = new EncoderParameter(encoder
(long)EncoderValue.Flush)
pagebitmap.SaveAdd(ep)




using (FileStream reader = new FileStream(tempfilename
FileMode.Open, FileAccess.Read)


buffer = new byte[reader.Length]

reader.Read(buffer, 0, (int)reader.Length)

reader.Close()


finall

GC.Collect()

if (pagebitmap != null

pagebitmap.Dispose()


if (image != null)

Previous Posts In This Thread:

EggHeadCafe - Software Developer Portal of Choice
JavaScript - Modal Dialog Box - Cross Browser
http://www.eggheadcafe.com/tutorial...c8-0f561ff9f681/javascript--modal-dialog.aspx
 
(e-mail address removed)

Hi ELandry

pagebitmap = image.Clone(new Rectangle(0, 0
image.Width, image.Height), PixelFormat.Format1bppIndexed); //TODO: Out o
Memory exceptio

the solution is :

Replace the above code with the below code and Add the ConvertToBlackAndWhite method to project.

ConvertToBlackAndWhite(image, ref pagebitmap );




// Code block
publicvoid ConvertToBlackAndWhite(Bitmap original, refBitmap destination)

{

float hr = (float)original.VerticalResolution;

Size iSize = newSize(original.Width, original.Height);

BitmapData sourceData = original.LockBits(newRectangle(0, 0, iSize.Width, iSize.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

int imageSize = sourceData.Stride * sourceData.Height;

byte[] sourceBuffer = newbyte[imageSize + 1];

Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

original.UnlockBits(sourceData);

if (destination != null)

{

destination.Dispose();

GC.Collect(2);

}

destination =
newBitmap(iSize.Width, iSize.Height, PixelFormat.Format1bppIndexed);

destination.SetResolution(hr, hr);

BitmapData destinationData = destination.LockBits(newRectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

imageSize = destinationData.Stride * destinationData.Height;

byte[] destinationBuffer = newbyte[imageSize + 1];

int sourceIndex = 0;

int destinationIndex = 0;

long pixelTotal = 0;

byte destinationValue = 0;

int pixelValue = 128;

int height = iSize.Height;

int width = iSize.Width;

int threshold = 500;

int y = 0;

while (y < height)

{

sourceIndex = y * sourceData.Stride;

destinationIndex = y * destinationData.Stride;

destinationValue = 0;

pixelValue = 128;

int x = 0;

while (x < width)

{

pixelTotal = (
long)sourceBuffer[sourceIndex + 1] + (long)sourceBuffer[sourceIndex + 2] + (long)sourceBuffer[sourceIndex + 3];

if (pixelTotal > threshold)

{

destinationValue += (
byte)pixelValue;

}

if (pixelValue == 1)

{

destinationBuffer[destinationIndex] = destinationValue;

System.
Math.Min(System.Threading.Interlocked.Increment(ref destinationIndex), destinationIndex - 1);

destinationValue = 0;

pixelValue = 128;

}

else

{

pixelValue >>= 1;

}

sourceIndex += 4;

System.
Math.Min(System.Threading.Interlocked.Increment(ref x), x - 1);

}

if (!(pixelValue == 128))

{

destinationBuffer[destinationIndex] = destinationValue;

}

System.
Math.Min(System.Threading.Interlocked.Increment(ref y), y - 1);

}

Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);

destination.UnlockBits(destinationData);

sourceBuffer =
null;

destinationBuffer =
null;

sourceData =
null;

destinationData =
null;

GC.Collect(2);

GC.WaitForPendingFinalizers();

}


Compression should be CCITT3 or 4. else it will produce GDI+ Error.

Have a nice day

 
Last edited:
Back
Top